]> git.lizzy.rs Git - rust.git/commitdiff
rollup merge of #20081: tomjakubowski/issue-19646
authorAlex Crichton <alex@alexcrichton.com>
Sun, 21 Dec 2014 08:04:28 +0000 (00:04 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Sun, 21 Dec 2014 17:27:37 +0000 (09:27 -0800)
Encode foreign item attributes and stability levels and visit foreign
items in the stability visitor.

cc @Gankro

1  2 
src/librustc/middle/stability.rs

index c4a5fd2f14a3ccd739779dcc83ec1cb82bbcb516,3e874f46a338c5ca9971f75834c0468c5fe59298..9d032df67dc8bcd461a81afe726c291c0f03cfeb
@@@ -43,8 -43,7 +43,8 @@@ struct Annotator 
  impl Annotator {
      // 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, attrs: &Vec<Attribute>, f: F) where
 +    fn annotate<F>(&mut self, id: NodeId, use_parent: bool,
 +                   attrs: &Vec<Attribute>, f: F) where
          F: FnOnce(&mut Annotator),
      {
          match attr::find_stability(attrs.as_slice()) {
@@@ -61,9 -60,7 +61,9 @@@
                  }
              }
              None => {
 -                self.parent.clone().map(|stab| self.index.local.insert(id, stab));
 +                if use_parent {
 +                    self.parent.clone().map(|stab| self.index.local.insert(id, stab));
 +                }
                  f(self);
              }
          }
  
  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));
 +        // FIXME (#18969): the following is a hack around the fact
 +        // that we cannot currently annotate the stability of
 +        // `deriving`.  Basically, we do *not* allow stability
 +        // inheritance on trait implementations, so that derived
 +        // implementations appear to be unannotated. This then allows
 +        // derived implementations to be automatically tagged with the
 +        // stability of the trait. This is WRONG, but expedient to get
 +        // libstd stabilized for the 1.0 release.
 +        let use_parent = match i.node {
 +            ast::ItemImpl(_, _, Some(_), _, _) => false,
 +            _ => true,
 +        };
 +
 +        self.annotate(i.id, use_parent, &i.attrs, |v| visit::walk_item(v, i));
  
          if let ast::ItemStruct(ref sd, _) = i.node {
              sd.ctor_id.map(|id| {
 -                self.annotate(id, &i.attrs, |_| {})
 +                self.annotate(id, true, &i.attrs, |_| {})
              });
          }
      }
@@@ -98,7 -82,7 +98,7 @@@
                  _: &'v Block, _: Span, _: NodeId) {
          if let FkMethod(_, _, meth) = fk {
              // Methods are not already annotated, so we annotate it
 -            self.annotate(meth.id, &meth.attrs, |_| {});
 +            self.annotate(meth.id, true, &meth.attrs, |_| {});
          }
          // Items defined in a function body have no reason to have
          // a stability attribute, so we don't recurse.
  
              TypeTraitItem(ref typedef) => (typedef.ty_param.id, &typedef.attrs),
          };
 -        self.annotate(id, attrs, |v| visit::walk_trait_item(v, t));
 +        self.annotate(id, true, attrs, |v| visit::walk_trait_item(v, t));
      }
  
      fn visit_variant(&mut self, var: &Variant, g: &'v Generics) {
 -        self.annotate(var.node.id, &var.node.attrs, |v| visit::walk_variant(v, var, g))
 +        self.annotate(var.node.id, true, &var.node.attrs,
 +                      |v| visit::walk_variant(v, var, g))
      }
  
      fn visit_struct_field(&mut self, s: &StructField) {
 -        self.annotate(s.node.id, &s.node.attrs, |v| visit::walk_struct_field(v, s));
 +        self.annotate(s.node.id, true, &s.node.attrs,
 +                      |v| visit::walk_struct_field(v, s));
      }
+     fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
+         self.annotate(i.id, &i.attrs, |_| {});
+     }
  }
  
  impl Index {
              },
              parent: None
          };
 -        annotator.annotate(ast::CRATE_NODE_ID, &krate.attrs, |v| visit::walk_crate(v, krate));
 +        annotator.annotate(ast::CRATE_NODE_ID, true, &krate.attrs,
 +                           |v| visit::walk_crate(v, krate));
          annotator.index
      }
  }
@@@ -154,29 -139,16 +158,29 @@@ pub fn lookup(tcx: &ty::ctxt, id: DefId
      match ty::trait_item_of_item(tcx, id) {
          Some(ty::MethodTraitItemId(trait_method_id))
                  if trait_method_id != id => {
 -            lookup(tcx, trait_method_id)
 -        }
 -        _ if is_local(id) => {
 -            tcx.stability.borrow().local.get(&id.node).cloned()
 -        }
 -        _ => {
 -            let stab = csearch::get_stability(&tcx.sess.cstore, id);
 -            let mut index = tcx.stability.borrow_mut();
 -            (*index).extern_cache.insert(id, stab.clone());
 -            stab
 +            return lookup(tcx, trait_method_id)
          }
 +        _ => {}
      }
 +
 +    let item_stab = if is_local(id) {
 +        tcx.stability.borrow().local.get(&id.node).cloned()
 +    } else {
 +        let stab = csearch::get_stability(&tcx.sess.cstore, id);
 +        let mut index = tcx.stability.borrow_mut();
 +        (*index).extern_cache.insert(id, stab.clone());
 +        stab
 +    };
 +
 +    item_stab.or_else(|| {
 +        if let Some(trait_id) = ty::trait_id_of_impl(tcx, id) {
 +            // FIXME (#18969): for the time being, simply use the
 +            // stability of the trait to determine the stability of any
 +            // unmarked impls for it. See FIXME above for more details.
 +
 +            lookup(tcx, trait_id)
 +        } else {
 +            None
 +        }
 +    })
  }