about summary refs log tree commit diff
path: root/compiler/rustc_passes/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-27 12:51:21 +0000
committerbors <bors@rust-lang.org>2020-09-27 12:51:21 +0000
commitd902752866cbbdb331e3cf28ff6bba86ab0f6c62 (patch)
tree94ffd454f33732663936012eda8cafa4a24b23e2 /compiler/rustc_passes/src
parentb8363295d555494bbaa119eba8b16a3057e6728c (diff)
parent98eab09cf4ee1a35290a2061ee0e7a19703923a8 (diff)
downloadrust-d902752866cbbdb331e3cf28ff6bba86ab0f6c62.tar.gz
rust-d902752866cbbdb331e3cf28ff6bba86ab0f6c62.zip
Auto merge of #77118 - exrook:stability-generic-parameters-2, r=varkor
 Stability annotations on generic parameters (take 2.5)

Rebase of #72314 + more tests

Implements rust-lang/wg-allocators#2.
Diffstat (limited to 'compiler/rustc_passes/src')
-rw-r--r--compiler/rustc_passes/src/stability.rs148
1 files changed, 122 insertions, 26 deletions
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 4ca52f405fb..b807dff5fd2 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -37,6 +37,24 @@ enum AnnotationKind {
     Container,
 }
 
+/// Whether to inherit deprecation flags for nested items. In most cases, we do want to inherit
+/// deprecation, because nested items rarely have individual deprecation attributes, and so
+/// should be treated as deprecated if their parent is. However, default generic parameters
+/// have separate deprecation attributes from their parents, so we do not wish to inherit
+/// deprecation in this case. For example, inheriting deprecation for `T` in `Foo<T>`
+/// would cause a duplicate warning arising from both `Foo` and `T` being deprecated.
+#[derive(Clone)]
+enum InheritDeprecation {
+    Yes,
+    No,
+}
+
+impl InheritDeprecation {
+    fn yes(&self) -> bool {
+        matches!(self, InheritDeprecation::Yes)
+    }
+}
+
 // A private tree-walker for producing an Index.
 struct Annotator<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -56,6 +74,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         attrs: &[Attribute],
         item_sp: Span,
         kind: AnnotationKind,
+        inherit_deprecation: InheritDeprecation,
         visit_children: F,
     ) where
         F: FnOnce(&mut Self),
@@ -63,7 +82,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs);
         let mut did_error = false;
         if !self.tcx.features().staged_api {
-            did_error = self.forbid_staged_api_attrs(hir_id, attrs);
+            did_error = self.forbid_staged_api_attrs(hir_id, attrs, inherit_deprecation.clone());
         }
 
         let depr =
@@ -80,9 +99,11 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
             let depr_entry = DeprecationEntry::local(depr.clone(), hir_id);
             self.index.depr_map.insert(hir_id, depr_entry);
         } else if let Some(parent_depr) = self.parent_depr.clone() {
-            is_deprecated = true;
-            info!("tagging child {:?} as deprecated from parent", hir_id);
-            self.index.depr_map.insert(hir_id, parent_depr);
+            if inherit_deprecation.yes() {
+                is_deprecated = true;
+                info!("tagging child {:?} as deprecated from parent", hir_id);
+                self.index.depr_map.insert(hir_id, parent_depr);
+            }
         }
 
         if self.tcx.features().staged_api {
@@ -186,7 +207,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         if stab.is_none() {
             debug!("annotate: stab not found, parent = {:?}", self.parent_stab);
             if let Some(stab) = self.parent_stab {
-                if stab.level.is_unstable() {
+                if inherit_deprecation.yes() && stab.level.is_unstable() {
                     self.index.stab_map.insert(hir_id, stab);
                 }
             }
@@ -237,7 +258,12 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
     }
 
     // returns true if an error occurred, used to suppress some spurious errors
-    fn forbid_staged_api_attrs(&mut self, hir_id: HirId, attrs: &[Attribute]) -> bool {
+    fn forbid_staged_api_attrs(
+        &mut self,
+        hir_id: HirId,
+        attrs: &[Attribute],
+        inherit_deprecation: InheritDeprecation,
+    ) -> bool {
         // Emit errors for non-staged-api crates.
         let unstable_attrs = [
             sym::unstable,
@@ -265,7 +291,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         // Propagate unstability.  This can happen even for non-staged-api crates in case
         // -Zforce-unstable-if-unmarked is set.
         if let Some(stab) = self.parent_stab {
-            if stab.level.is_unstable() {
+            if inherit_deprecation.yes() && stab.level.is_unstable() {
                 self.index.stab_map.insert(hir_id, stab);
             }
         }
@@ -301,54 +327,119 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             }
             hir::ItemKind::Struct(ref sd, _) => {
                 if let Some(ctor_hir_id) = sd.ctor_hir_id() {
-                    self.annotate(ctor_hir_id, &i.attrs, i.span, AnnotationKind::Required, |_| {})
+                    self.annotate(
+                        ctor_hir_id,
+                        &i.attrs,
+                        i.span,
+                        AnnotationKind::Required,
+                        InheritDeprecation::Yes,
+                        |_| {},
+                    )
                 }
             }
             _ => {}
         }
 
-        self.annotate(i.hir_id, &i.attrs, i.span, kind, |v| intravisit::walk_item(v, i));
+        self.annotate(i.hir_id, &i.attrs, i.span, kind, InheritDeprecation::Yes, |v| {
+            intravisit::walk_item(v, i)
+        });
         self.in_trait_impl = orig_in_trait_impl;
     }
 
     fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) {
-        self.annotate(ti.hir_id, &ti.attrs, ti.span, AnnotationKind::Required, |v| {
-            intravisit::walk_trait_item(v, ti);
-        });
+        self.annotate(
+            ti.hir_id,
+            &ti.attrs,
+            ti.span,
+            AnnotationKind::Required,
+            InheritDeprecation::Yes,
+            |v| {
+                intravisit::walk_trait_item(v, ti);
+            },
+        );
     }
 
     fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
         let kind =
             if self.in_trait_impl { AnnotationKind::Prohibited } else { AnnotationKind::Required };
-        self.annotate(ii.hir_id, &ii.attrs, ii.span, kind, |v| {
+        self.annotate(ii.hir_id, &ii.attrs, ii.span, kind, InheritDeprecation::Yes, |v| {
             intravisit::walk_impl_item(v, ii);
         });
     }
 
     fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics<'tcx>, item_id: HirId) {
-        self.annotate(var.id, &var.attrs, var.span, AnnotationKind::Required, |v| {
-            if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
-                v.annotate(ctor_hir_id, &var.attrs, var.span, AnnotationKind::Required, |_| {});
-            }
+        self.annotate(
+            var.id,
+            &var.attrs,
+            var.span,
+            AnnotationKind::Required,
+            InheritDeprecation::Yes,
+            |v| {
+                if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
+                    v.annotate(
+                        ctor_hir_id,
+                        &var.attrs,
+                        var.span,
+                        AnnotationKind::Required,
+                        InheritDeprecation::Yes,
+                        |_| {},
+                    );
+                }
 
-            intravisit::walk_variant(v, var, g, item_id)
-        })
+                intravisit::walk_variant(v, var, g, item_id)
+            },
+        )
     }
 
     fn visit_struct_field(&mut self, s: &'tcx StructField<'tcx>) {
-        self.annotate(s.hir_id, &s.attrs, s.span, AnnotationKind::Required, |v| {
-            intravisit::walk_struct_field(v, s);
-        });
+        self.annotate(
+            s.hir_id,
+            &s.attrs,
+            s.span,
+            AnnotationKind::Required,
+            InheritDeprecation::Yes,
+            |v| {
+                intravisit::walk_struct_field(v, s);
+            },
+        );
     }
 
     fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem<'tcx>) {
-        self.annotate(i.hir_id, &i.attrs, i.span, AnnotationKind::Required, |v| {
-            intravisit::walk_foreign_item(v, i);
-        });
+        self.annotate(
+            i.hir_id,
+            &i.attrs,
+            i.span,
+            AnnotationKind::Required,
+            InheritDeprecation::Yes,
+            |v| {
+                intravisit::walk_foreign_item(v, i);
+            },
+        );
     }
 
     fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
-        self.annotate(md.hir_id, &md.attrs, md.span, AnnotationKind::Required, |_| {});
+        self.annotate(
+            md.hir_id,
+            &md.attrs,
+            md.span,
+            AnnotationKind::Required,
+            InheritDeprecation::Yes,
+            |_| {},
+        );
+    }
+
+    fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
+        let kind = match &p.kind {
+            // FIXME(const_generics:defaults)
+            hir::GenericParamKind::Type { default, .. } if default.is_some() => {
+                AnnotationKind::Container
+            }
+            _ => AnnotationKind::Prohibited,
+        };
+
+        self.annotate(p.hir_id, &p.attrs, p.span, kind, InheritDeprecation::No, |v| {
+            intravisit::walk_generic_param(v, p);
+        });
     }
 }
 
@@ -422,6 +513,10 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
     fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
         self.check_missing_stability(md.hir_id, md.span);
     }
+
+    // Note that we don't need to `check_missing_stability` for default generic parameters,
+    // as we assume that any default generic parameters without attributes are automatically
+    // stable (assuming they have not inherited instability from their parent).
 }
 
 fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
@@ -484,6 +579,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
             &krate.item.attrs,
             krate.item.span,
             AnnotationKind::Required,
+            InheritDeprecation::Yes,
             |v| intravisit::walk_crate(v, krate),
         );
     }