|
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