diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 7f6a73c83fa76..3b7ad9e8f6b34 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 4016a76206be4..5691ce3bfa740 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 483a3b6d66787..ba8559c8008bf 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();