|
1 | 1 | //! A pass that annotates every item and method with its stability level,
|
2 | 2 | //! propagating default levels lexically from parent to children ast nodes.
|
3 | 3 |
|
4 |
| -use rustc_ast::Attribute; |
5 | 4 | use rustc_attr::{self as attr, ConstStability, Stability};
|
6 | 5 | use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
7 | 6 | use rustc_errors::struct_span_err;
|
8 | 7 | use rustc_hir as hir;
|
9 | 8 | use rustc_hir::def::{DefKind, Res};
|
10 |
| -use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE}; |
| 9 | +use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX}; |
11 | 10 | use rustc_hir::hir_id::CRATE_HIR_ID;
|
12 | 11 | use rustc_hir::intravisit::{self, Visitor};
|
13 | 12 | use rustc_hir::{FieldDef, Generics, HirId, Item, TraitRef, Ty, TyKind, Variant};
|
@@ -113,12 +112,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
113 | 112 | {
|
114 | 113 | let attrs = self.tcx.get_attrs(def_id.to_def_id());
|
115 | 114 | debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs);
|
116 |
| - let mut did_error = false; |
117 |
| - if !self.tcx.features().staged_api { |
118 |
| - did_error = self.forbid_staged_api_attrs(def_id, attrs, inherit_deprecation.clone()); |
119 |
| - } |
120 | 115 |
|
121 |
| - let depr = if did_error { None } else { attr::find_deprecation(&self.tcx.sess, attrs) }; |
| 116 | + let depr = attr::find_deprecation(&self.tcx.sess, attrs); |
122 | 117 | let mut is_deprecated = false;
|
123 | 118 | if let Some((depr, span)) = &depr {
|
124 | 119 | is_deprecated = true;
|
@@ -148,16 +143,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
148 | 143 | }
|
149 | 144 | }
|
150 | 145 |
|
151 |
| - if self.tcx.features().staged_api { |
152 |
| - if let Some(a) = attrs.iter().find(|a| a.has_name(sym::deprecated)) { |
153 |
| - self.tcx |
154 |
| - .sess |
155 |
| - .struct_span_err(a.span, "`#[deprecated]` cannot be used in staged API") |
156 |
| - .span_label(a.span, "use `#[rustc_deprecated]` instead") |
157 |
| - .span_label(item_sp, "") |
158 |
| - .emit(); |
| 146 | + if !self.tcx.features().staged_api { |
| 147 | + // Propagate unstability. This can happen even for non-staged-api crates in case |
| 148 | + // -Zforce-unstable-if-unmarked is set. |
| 149 | + if let Some(stab) = self.parent_stab { |
| 150 | + if inherit_deprecation.yes() && stab.level.is_unstable() { |
| 151 | + self.index.stab_map.insert(def_id, stab); |
| 152 | + } |
159 | 153 | }
|
160 |
| - } else { |
| 154 | + |
161 | 155 | self.recurse_with_stability_attrs(
|
162 | 156 | depr.map(|(d, _)| DeprecationEntry::local(d, def_id)),
|
163 | 157 | None,
|
@@ -331,47 +325,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
331 | 325 | self.parent_const_stab = orig_parent_const_stab;
|
332 | 326 | }
|
333 | 327 | }
|
334 |
| - |
335 |
| - // returns true if an error occurred, used to suppress some spurious errors |
336 |
| - fn forbid_staged_api_attrs( |
337 |
| - &mut self, |
338 |
| - def_id: LocalDefId, |
339 |
| - attrs: &[Attribute], |
340 |
| - inherit_deprecation: InheritDeprecation, |
341 |
| - ) -> bool { |
342 |
| - // Emit errors for non-staged-api crates. |
343 |
| - let unstable_attrs = [ |
344 |
| - sym::unstable, |
345 |
| - sym::stable, |
346 |
| - sym::rustc_deprecated, |
347 |
| - sym::rustc_const_unstable, |
348 |
| - sym::rustc_const_stable, |
349 |
| - ]; |
350 |
| - let mut has_error = false; |
351 |
| - for attr in attrs { |
352 |
| - let name = attr.name_or_empty(); |
353 |
| - if unstable_attrs.contains(&name) { |
354 |
| - struct_span_err!( |
355 |
| - self.tcx.sess, |
356 |
| - attr.span, |
357 |
| - E0734, |
358 |
| - "stability attributes may not be used outside of the standard library", |
359 |
| - ) |
360 |
| - .emit(); |
361 |
| - has_error = true; |
362 |
| - } |
363 |
| - } |
364 |
| - |
365 |
| - // Propagate unstability. This can happen even for non-staged-api crates in case |
366 |
| - // -Zforce-unstable-if-unmarked is set. |
367 |
| - if let Some(stab) = self.parent_stab { |
368 |
| - if inherit_deprecation.yes() && stab.level.is_unstable() { |
369 |
| - self.index.stab_map.insert(def_id, stab); |
370 |
| - } |
371 |
| - } |
372 |
| - |
373 |
| - has_error |
374 |
| - } |
375 | 328 | }
|
376 | 329 |
|
377 | 330 | impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
@@ -656,28 +609,12 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
|
656 | 609 | }
|
657 | 610 |
|
658 | 611 | fn stability_index<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> Index<'tcx> {
|
659 |
| - let is_staged_api = |
660 |
| - tcx.sess.opts.debugging_opts.force_unstable_if_unmarked || tcx.features().staged_api; |
661 |
| - let mut staged_api = FxHashMap::default(); |
662 |
| - staged_api.insert(LOCAL_CRATE, is_staged_api); |
663 | 612 | let mut index = Index {
|
664 |
| - staged_api, |
665 | 613 | stab_map: Default::default(),
|
666 | 614 | const_stab_map: Default::default(),
|
667 | 615 | depr_map: Default::default(),
|
668 |
| - active_features: Default::default(), |
669 | 616 | };
|
670 | 617 |
|
671 |
| - let active_lib_features = &tcx.features().declared_lib_features; |
672 |
| - let active_lang_features = &tcx.features().declared_lang_features; |
673 |
| - |
674 |
| - // Put the active features into a map for quick lookup. |
675 |
| - index.active_features = active_lib_features |
676 |
| - .iter() |
677 |
| - .map(|&(s, ..)| s) |
678 |
| - .chain(active_lang_features.iter().map(|&(s, ..)| s)) |
679 |
| - .collect(); |
680 |
| - |
681 | 618 | {
|
682 | 619 | let mut annotator = Annotator {
|
683 | 620 | tcx,
|
@@ -730,7 +667,16 @@ fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
|
730 | 667 | }
|
731 | 668 |
|
732 | 669 | pub(crate) fn provide(providers: &mut Providers) {
|
733 |
| - *providers = Providers { check_mod_unstable_api_usage, stability_index, ..*providers }; |
| 670 | + *providers = Providers { |
| 671 | + check_mod_unstable_api_usage, |
| 672 | + stability_index, |
| 673 | + lookup_stability: |tcx, id| tcx.stability().local_stability(id.expect_local()), |
| 674 | + lookup_const_stability: |tcx, id| tcx.stability().local_const_stability(id.expect_local()), |
| 675 | + lookup_deprecation_entry: |tcx, id| { |
| 676 | + tcx.stability().local_deprecation_entry(id.expect_local()) |
| 677 | + }, |
| 678 | + ..*providers |
| 679 | + }; |
734 | 680 | }
|
735 | 681 |
|
736 | 682 | struct Checker<'tcx> {
|
@@ -886,9 +832,10 @@ impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> {
|
886 | 832 | /// were expected to be library features), and the list of features used from
|
887 | 833 | /// libraries, identify activated features that don't exist and error about them.
|
888 | 834 | pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
|
889 |
| - let access_levels = &tcx.privacy_access_levels(()); |
890 |
| - |
891 |
| - if tcx.stability().staged_api[&LOCAL_CRATE] { |
| 835 | + let is_staged_api = |
| 836 | + tcx.sess.opts.debugging_opts.force_unstable_if_unmarked || tcx.features().staged_api; |
| 837 | + if is_staged_api { |
| 838 | + let access_levels = &tcx.privacy_access_levels(()); |
892 | 839 | let mut missing = MissingStabilityAnnotations { tcx, access_levels };
|
893 | 840 | missing.check_missing_stability(CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID));
|
894 | 841 | tcx.hir().walk_toplevel_module(&mut missing);
|
|
0 commit comments