about summary refs log tree commit diff
path: root/compiler/rustc_passes/src
diff options
context:
space:
mode:
authoroli <github35764891676564198441@oli-obk.de>2021-01-16 19:59:21 +0000
committeroli <github35764891676564198441@oli-obk.de>2021-01-18 11:07:35 +0000
commit5bac1c9229331105bab558f7d3be1685a76d110c (patch)
tree3dcf06739c67b9d3c64111ab82308acff2e5fabd /compiler/rustc_passes/src
parent949bdd8b79a48ac25408f9cfb0e9d57a75d5f12b (diff)
downloadrust-5bac1c9229331105bab558f7d3be1685a76d110c.tar.gz
rust-5bac1c9229331105bab558f7d3be1685a76d110c.zip
Only inherit const stability for methods of `impl const Trait` blocks
Diffstat (limited to 'compiler/rustc_passes/src')
-rw-r--r--compiler/rustc_passes/src/stability.rs70
1 files changed, 60 insertions, 10 deletions
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 4a3d6ecf8cc..b70cec25dfb 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -55,6 +55,21 @@ impl InheritDeprecation {
     }
 }
 
+/// Whether to inherit const stability flags for nested items. In most cases, we do not want to
+/// inherit const stability: just because an enclosing `fn` is const-stable does not mean
+/// all `extern` imports declared in it should be const-stable! However, trait methods
+/// inherit const stability attributes from their parent and do not have their own.
+enum InheritConstStability {
+    Yes,
+    No,
+}
+
+impl InheritConstStability {
+    fn yes(&self) -> bool {
+        matches!(self, InheritConstStability::Yes)
+    }
+}
+
 // A private tree-walker for producing an Index.
 struct Annotator<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -75,6 +90,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         item_sp: Span,
         kind: AnnotationKind,
         inherit_deprecation: InheritDeprecation,
+        inherit_const_stability: InheritConstStability,
         visit_children: F,
     ) where
         F: FnOnce(&mut Self),
@@ -140,6 +156,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
             const_stab
         });
 
+        // `impl const Trait for Type` items forward their const stability to their
+        // immediate children.
         if const_stab.is_none() {
             debug!("annotate: const_stab not found, parent = {:?}", self.parent_const_stab);
             if let Some(parent) = self.parent_const_stab {
@@ -228,7 +246,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         self.recurse_with_stability_attrs(
             depr.map(|(d, _)| DeprecationEntry::local(d, hir_id)),
             stab,
-            const_stab,
+            if inherit_const_stability.yes() { const_stab } else { None },
             visit_children,
         );
     }
@@ -325,6 +343,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
     fn visit_item(&mut self, i: &'tcx Item<'tcx>) {
         let orig_in_trait_impl = self.in_trait_impl;
         let mut kind = AnnotationKind::Required;
+        let mut const_stab_inherit = InheritConstStability::No;
         match i.kind {
             // Inherent impls and foreign modules serve only as containers for other items,
             // they don't have their own stability. They still can be annotated as unstable
@@ -338,6 +357,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => {
                 self.in_trait_impl = true;
                 kind = AnnotationKind::DeprecationProhibited;
+                const_stab_inherit = InheritConstStability::Yes;
             }
             hir::ItemKind::Struct(ref sd, _) => {
                 if let Some(ctor_hir_id) = sd.ctor_hir_id() {
@@ -347,6 +367,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
                         i.span,
                         AnnotationKind::Required,
                         InheritDeprecation::Yes,
+                        InheritConstStability::No,
                         |_| {},
                     )
                 }
@@ -354,9 +375,15 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             _ => {}
         }
 
-        self.annotate(i.hir_id, &i.attrs, i.span, kind, InheritDeprecation::Yes, |v| {
-            intravisit::walk_item(v, i)
-        });
+        self.annotate(
+            i.hir_id,
+            &i.attrs,
+            i.span,
+            kind,
+            InheritDeprecation::Yes,
+            const_stab_inherit,
+            |v| intravisit::walk_item(v, i),
+        );
         self.in_trait_impl = orig_in_trait_impl;
     }
 
@@ -367,6 +394,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             ti.span,
             AnnotationKind::Required,
             InheritDeprecation::Yes,
+            InheritConstStability::No,
             |v| {
                 intravisit::walk_trait_item(v, ti);
             },
@@ -376,9 +404,17 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
     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, InheritDeprecation::Yes, |v| {
-            intravisit::walk_impl_item(v, ii);
-        });
+        self.annotate(
+            ii.hir_id,
+            &ii.attrs,
+            ii.span,
+            kind,
+            InheritDeprecation::Yes,
+            InheritConstStability::No,
+            |v| {
+                intravisit::walk_impl_item(v, ii);
+            },
+        );
     }
 
     fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics<'tcx>, item_id: HirId) {
@@ -388,6 +424,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             var.span,
             AnnotationKind::Required,
             InheritDeprecation::Yes,
+            InheritConstStability::No,
             |v| {
                 if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
                     v.annotate(
@@ -396,6 +433,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
                         var.span,
                         AnnotationKind::Required,
                         InheritDeprecation::Yes,
+                        InheritConstStability::No,
                         |_| {},
                     );
                 }
@@ -412,6 +450,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             s.span,
             AnnotationKind::Required,
             InheritDeprecation::Yes,
+            InheritConstStability::No,
             |v| {
                 intravisit::walk_struct_field(v, s);
             },
@@ -425,6 +464,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             i.span,
             AnnotationKind::Required,
             InheritDeprecation::Yes,
+            InheritConstStability::No,
             |v| {
                 intravisit::walk_foreign_item(v, i);
             },
@@ -438,6 +478,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             md.span,
             AnnotationKind::Required,
             InheritDeprecation::Yes,
+            InheritConstStability::No,
             |_| {},
         );
     }
@@ -451,9 +492,17 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             _ => AnnotationKind::Prohibited,
         };
 
-        self.annotate(p.hir_id, &p.attrs, p.span, kind, InheritDeprecation::No, |v| {
-            intravisit::walk_generic_param(v, p);
-        });
+        self.annotate(
+            p.hir_id,
+            &p.attrs,
+            p.span,
+            kind,
+            InheritDeprecation::No,
+            InheritConstStability::No,
+            |v| {
+                intravisit::walk_generic_param(v, p);
+            },
+        );
     }
 }
 
@@ -618,6 +667,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
             krate.item.span,
             AnnotationKind::Required,
             InheritDeprecation::Yes,
+            InheritConstStability::No,
             |v| intravisit::walk_crate(v, krate),
         );
     }