提交 6ec5a0f6 编写于 作者: M Manish Goregaokar

Error when #![staged_api] crates are missing stability markers

上级 0b9e227a
......@@ -14,6 +14,7 @@
use session::Session;
use lint;
use middle::ty;
use middle::privacy::PublicItems;
use metadata::csearch;
use syntax::parse::token::InternedString;
use syntax::codemap::{Span, DUMMY_SP};
......@@ -45,14 +46,15 @@ pub struct Index {
struct Annotator<'a> {
sess: &'a Session,
index: &'a mut Index,
parent: Option<Stability>
parent: Option<Stability>,
export_map: &'a PublicItems,
}
impl<'a> Annotator<'a> {
// Determine the stability for a node based on its attributes and inherited
// stability. The stability is recorded in the index and used as the parent.
fn annotate<F>(&mut self, id: NodeId, use_parent: bool,
attrs: &Vec<Attribute>, item_sp: Span, f: F) where
attrs: &Vec<Attribute>, item_sp: Span, f: F, required: bool) where
F: FnOnce(&mut Annotator),
{
match attr::find_stability(self.sess.diagnostic(), attrs.as_slice(), item_sp) {
......@@ -70,7 +72,13 @@ fn annotate<F>(&mut self, id: NodeId, use_parent: bool,
}
None => {
if use_parent {
self.parent.clone().map(|stab| self.index.local.insert(id, stab));
if let Some(stab) = self.parent.clone() {
self.index.local.insert(id, stab);
} else if self.index.staged_api && required
&& self.export_map.contains(&id) {
self.sess.span_err(item_sp,
"This node does not have a stability attribute");
}
}
f(self);
}
......@@ -93,11 +101,19 @@ fn visit_item(&mut self, i: &Item) {
_ => true,
};
self.annotate(i.id, use_parent, &i.attrs, i.span, |v| visit::walk_item(v, i));
// In case of a `pub use <mod>;`, we should not error since the stability
// is inherited from the module itself
let required = match i.node {
ast::ItemUse(_) => i.vis != ast::Public,
_ => true
};
self.annotate(i.id, use_parent, &i.attrs, i.span,
|v| visit::walk_item(v, i), required);
if let ast::ItemStruct(ref sd, _) = i.node {
sd.ctor_id.map(|id| {
self.annotate(id, true, &i.attrs, i.span, |_| {})
self.annotate(id, true, &i.attrs, i.span, |_| {}, true)
});
}
}
......@@ -106,7 +122,7 @@ fn visit_fn(&mut self, fk: FnKind<'v>, _: &'v FnDecl,
_: &'v Block, sp: Span, _: NodeId) {
if let FkMethod(_, _, meth) = fk {
// Methods are not already annotated, so we annotate it
self.annotate(meth.id, true, &meth.attrs, sp, |_| {});
self.annotate(meth.id, true, &meth.attrs, sp, |_| {}, true);
}
// Items defined in a function body have no reason to have
// a stability attribute, so we don't recurse.
......@@ -126,37 +142,38 @@ fn visit_trait_item(&mut self, t: &TraitItem) {
TypeTraitItem(ref typedef) => (typedef.ty_param.id, &typedef.attrs,
typedef.ty_param.span),
};
self.annotate(id, true, attrs, sp, |v| visit::walk_trait_item(v, t));
self.annotate(id, true, attrs, sp, |v| visit::walk_trait_item(v, t), true);
}
fn visit_variant(&mut self, var: &Variant, g: &'v Generics) {
self.annotate(var.node.id, true, &var.node.attrs, var.span,
|v| visit::walk_variant(v, var, g))
|v| visit::walk_variant(v, var, g), true)
}
fn visit_struct_field(&mut self, s: &StructField) {
self.annotate(s.node.id, true, &s.node.attrs, s.span,
|v| visit::walk_struct_field(v, s));
|v| visit::walk_struct_field(v, s), true);
}
fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
self.annotate(i.id, true, &i.attrs, i.span, |_| {});
self.annotate(i.id, true, &i.attrs, i.span, |_| {}, true);
}
}
impl Index {
/// Construct the stability index for a crate being compiled.
pub fn build(&mut self, sess: &Session, krate: &Crate) {
pub fn build(&mut self, sess: &Session, krate: &Crate, export_map: &PublicItems) {
if !self.staged_api {
return;
}
let mut annotator = Annotator {
sess: sess,
index: self,
parent: None
parent: None,
export_map: export_map,
};
annotator.annotate(ast::CRATE_NODE_ID, true, &krate.attrs, krate.span,
|v| visit::walk_crate(v, krate));
|v| visit::walk_crate(v, krate), true);
}
pub fn new(krate: &Crate) -> Index {
......
......@@ -627,7 +627,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
// Do not move this check past lint
time(time_passes, "stability index", (), |_|
ty_cx.stability.borrow_mut().build(&ty_cx.sess, krate));
ty_cx.stability.borrow_mut().build(&ty_cx.sess, krate, &public_items));
time(time_passes, "intrinsic checking", (), |_|
middle::intrinsicck::check_crate(&ty_cx));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册