From 5b895a833a6443046bbc8a6362b1a957cf68d1b4 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Tue, 11 Nov 2014 12:46:47 -0800 Subject: [PATCH] rustc: do not inherit #[stable] 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 --- src/librustc/middle/stability.rs | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 7f6a73c83fa7..3b7ad9e8f6b3 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)); }