about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-11-13 19:32:21 +0000
committerbors <bors@rust-lang.org>2014-11-13 19:32:21 +0000
commit15ba87f0314fda5e81603f37ae5f40e2022bcfc1 (patch)
treeb65785eae17a8f621ee5a2f71c29f76a68e85e6e /src
parent37ea270accf97fc4eed21a7373c3e7e62de7bbeb (diff)
parent83521954267b3555bfb3a185a187b2c2d929e453 (diff)
downloadrust-15ba87f0314fda5e81603f37ae5f40e2022bcfc1.tar.gz
rust-15ba87f0314fda5e81603f37ae5f40e2022bcfc1.zip
auto merge of #18887 : aturon/rust/controlled-inherit, r=alexcrichton
This patch tweaks the stability inheritance infrastructure so that
`#{stable]` attributes are not inherited. Doing so solves two problems:

1. It allows us to mark module *names* as stable without accidentally
marking the items they contain as stable.

2. It means that a `#[stable]` attribution must always appear directly
on the item it applies to, which makes it easier for reviewers to catch
changes to stable APIs.

Fixes #17484
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/stability.rs31
-rw-r--r--src/test/auxiliary/inherited_stability.rs12
-rw-r--r--src/test/compile-fail/lint-stability.rs3
3 files changed, 32 insertions, 14 deletions
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 7f6a73c83fa..3b7ad9e8f6b 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -17,8 +17,7 @@ use syntax::{attr, visit};
 use syntax::ast;
 use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant};
 use syntax::ast::{Item, RequiredMethod, ProvidedMethod, TraitItem};
-use syntax::ast::{TypeMethod, Method, Generics, StructDef, StructField};
-use syntax::ast::{Ident, TypeTraitItem};
+use syntax::ast::{TypeMethod, Method, Generics, StructField, TypeTraitItem};
 use syntax::ast_util::is_local;
 use syntax::attr::Stability;
 use syntax::visit::{FnKind, FkMethod, Visitor};
@@ -48,9 +47,15 @@ impl Annotator {
         match attr::find_stability(attrs.as_slice()) {
             Some(stab) => {
                 self.index.local.insert(id, stab.clone());
-                let parent = replace(&mut self.parent, Some(stab));
-                f(self);
-                self.parent = parent;
+
+                // Don't inherit #[stable]
+                if stab.level != attr::Stable {
+                    let parent = replace(&mut self.parent, Some(stab));
+                    f(self);
+                    self.parent = parent;
+                } else {
+                    f(self);
+                }
             }
             None => {
                 self.parent.clone().map(|stab| self.index.local.insert(id, stab));
@@ -63,6 +68,15 @@ impl Annotator {
 impl<'v> Visitor<'v> for Annotator {
     fn visit_item(&mut self, i: &Item) {
         self.annotate(i.id, &i.attrs, |v| visit::walk_item(v, i));
+
+        match i.node {
+            ast::ItemStruct(ref sd, _) => {
+                sd.ctor_id.map(|id| {
+                    self.annotate(id, &i.attrs, |_| {})
+                });
+            }
+            _ => {}
+        }
     }
 
     fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl,
@@ -95,13 +109,6 @@ impl<'v> Visitor<'v> for Annotator {
         self.annotate(var.node.id, &var.node.attrs, |v| visit::walk_variant(v, var, g))
     }
 
-    fn visit_struct_def(&mut self, s: &StructDef, _: Ident, _: &Generics, _: NodeId) {
-        match s.ctor_id {
-            Some(id) => self.annotate(id, &vec![], |v| visit::walk_struct_def(v, s)),
-            None => visit::walk_struct_def(self, s)
-        }
-    }
-
     fn visit_struct_field(&mut self, s: &StructField) {
         self.annotate(s.node.id, &s.node.attrs, |v| visit::walk_struct_field(v, s));
     }
diff --git a/src/test/auxiliary/inherited_stability.rs b/src/test/auxiliary/inherited_stability.rs
index 4016a76206b..5691ce3bfa7 100644
--- a/src/test/auxiliary/inherited_stability.rs
+++ b/src/test/auxiliary/inherited_stability.rs
@@ -18,12 +18,20 @@ pub fn stable() {}
 
 #[stable]
 pub mod stable_mod {
-    #[experimental]
     pub fn experimental() {}
 
+    #[stable]
     pub fn stable() {}
 }
 
+#[unstable]
+pub mod unstable_mod {
+    #[experimental]
+    pub fn experimental() {}
+
+    pub fn unstable() {}
+}
+
 pub mod experimental_mod {
     pub fn experimental() {}
 
@@ -33,9 +41,9 @@ pub mod experimental_mod {
 
 #[stable]
 pub trait Stable {
-    #[experimental]
     fn experimental(&self);
 
+    #[stable]
     fn stable(&self);
 }
 
diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs
index 483a3b6d667..ba8559c8008 100644
--- a/src/test/compile-fail/lint-stability.rs
+++ b/src/test/compile-fail/lint-stability.rs
@@ -165,6 +165,9 @@ mod inheritance {
         stable_mod::experimental(); //~ ERROR use of experimental item
         stable_mod::stable();
 
+        unstable_mod::experimental(); //~ ERROR use of experimental item
+        unstable_mod::unstable(); //~ ERROR use of unstable item
+
         experimental_mod::experimental(); //~ ERROR use of experimental item
         experimental_mod::stable();