Skip to content

Commit

Permalink
auto merge of rust-lang#18887 : aturon/rust/controlled-inherit, r=ale…
Browse files Browse the repository at this point in the history
…xcrichton

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 rust-lang#17484
  • Loading branch information
bors committed Nov 13, 2014
2 parents 37ea270 + 8352195 commit 15ba87f
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 14 deletions.
31 changes: 19 additions & 12 deletions src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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));
Expand All @@ -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,
Expand Down Expand Up @@ -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));
}
Expand Down
12 changes: 10 additions & 2 deletions src/test/auxiliary/inherited_stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}

Expand All @@ -33,9 +41,9 @@ pub mod experimental_mod {

#[stable]
pub trait Stable {
#[experimental]
fn experimental(&self);

#[stable]
fn stable(&self);
}

Expand Down
3 changes: 3 additions & 0 deletions src/test/compile-fail/lint-stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down

0 comments on commit 15ba87f

Please sign in to comment.