mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 10:45:18 +00:00
Refactor attr::Stability
Stricter checking + enforcement of invariants at compile time
This commit is contained in:
parent
843e528fd0
commit
ab671552c3
@ -11,6 +11,8 @@
|
|||||||
//! A pass that annotates every item and method with its stability level,
|
//! A pass that annotates every item and method with its stability level,
|
||||||
//! propagating default levels lexically from parent to children ast nodes.
|
//! propagating default levels lexically from parent to children ast nodes.
|
||||||
|
|
||||||
|
pub use self::StabilityLevel::*;
|
||||||
|
|
||||||
use session::Session;
|
use session::Session;
|
||||||
use lint;
|
use lint;
|
||||||
use metadata::cstore::LOCAL_CRATE;
|
use metadata::cstore::LOCAL_CRATE;
|
||||||
@ -34,6 +36,18 @@ use rustc_front::visit::{self, FnKind, Visitor};
|
|||||||
use std::mem::replace;
|
use std::mem::replace;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Copy, Debug, Eq, Hash)]
|
||||||
|
pub enum StabilityLevel {
|
||||||
|
Unstable,
|
||||||
|
Stable,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StabilityLevel {
|
||||||
|
pub fn from_attr_level(level: &attr::StabilityLevel) -> Self {
|
||||||
|
if level.is_stable() { Stable } else { Unstable }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A stability index, giving the stability level for items and methods.
|
/// A stability index, giving the stability level for items and methods.
|
||||||
pub struct Index<'tcx> {
|
pub struct Index<'tcx> {
|
||||||
/// This is mostly a cache, except the stabilities of local items
|
/// This is mostly a cache, except the stabilities of local items
|
||||||
@ -67,10 +81,9 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
|
|||||||
// if parent is deprecated and we're not, inherit this by merging
|
// if parent is deprecated and we're not, inherit this by merging
|
||||||
// deprecated_since and its reason.
|
// deprecated_since and its reason.
|
||||||
if let Some(parent_stab) = self.parent {
|
if let Some(parent_stab) = self.parent {
|
||||||
if parent_stab.deprecated_since.is_some()
|
if parent_stab.depr.is_some()
|
||||||
&& stab.deprecated_since.is_none() {
|
&& stab.depr.is_none() {
|
||||||
stab.deprecated_since = parent_stab.deprecated_since.clone();
|
stab.depr = parent_stab.depr.clone()
|
||||||
stab.reason = parent_stab.reason.clone();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,9 +91,9 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
|
|||||||
|
|
||||||
// Check if deprecated_since < stable_since. If it is,
|
// Check if deprecated_since < stable_since. If it is,
|
||||||
// this is *almost surely* an accident.
|
// this is *almost surely* an accident.
|
||||||
let deprecated_predates_stable = match (stab.deprecated_since.as_ref(),
|
let deprecated_predates_stable = match (&stab.depr, &stab.level) {
|
||||||
stab.since.as_ref()) {
|
(&Some(attr::Deprecation {since: ref dep_since, ..}),
|
||||||
(Some(dep_since), Some(stab_since)) => {
|
&attr::Stable {since: ref stab_since}) => {
|
||||||
// explicit version of iter::order::lt to handle parse errors properly
|
// explicit version of iter::order::lt to handle parse errors properly
|
||||||
let mut is_less = false;
|
let mut is_less = false;
|
||||||
for (dep_v, stab_v) in dep_since.split(".").zip(stab_since.split(".")) {
|
for (dep_v, stab_v) in dep_since.split(".").zip(stab_since.split(".")) {
|
||||||
@ -117,7 +130,7 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
|
|||||||
self.index.map.insert(def_id, Some(stab));
|
self.index.map.insert(def_id, Some(stab));
|
||||||
|
|
||||||
// Don't inherit #[stable(feature = "rust1", since = "1.0.0")]
|
// Don't inherit #[stable(feature = "rust1", since = "1.0.0")]
|
||||||
if stab.level != attr::Stable {
|
if !stab.level.is_stable() {
|
||||||
let parent = replace(&mut self.parent, Some(stab));
|
let parent = replace(&mut self.parent, Some(stab));
|
||||||
f(self);
|
f(self);
|
||||||
self.parent = parent;
|
self.parent = parent;
|
||||||
@ -261,7 +274,7 @@ impl<'tcx> Index<'tcx> {
|
|||||||
/// features and possibly prints errors. Returns a list of all
|
/// features and possibly prints errors. Returns a list of all
|
||||||
/// features used.
|
/// features used.
|
||||||
pub fn check_unstable_api_usage(tcx: &ty::ctxt)
|
pub fn check_unstable_api_usage(tcx: &ty::ctxt)
|
||||||
-> FnvHashMap<InternedString, attr::StabilityLevel> {
|
-> FnvHashMap<InternedString, StabilityLevel> {
|
||||||
let ref active_lib_features = tcx.sess.features.borrow().declared_lib_features;
|
let ref active_lib_features = tcx.sess.features.borrow().declared_lib_features;
|
||||||
|
|
||||||
// Put the active features into a map for quick lookup
|
// Put the active features into a map for quick lookup
|
||||||
@ -284,7 +297,7 @@ pub fn check_unstable_api_usage(tcx: &ty::ctxt)
|
|||||||
struct Checker<'a, 'tcx: 'a> {
|
struct Checker<'a, 'tcx: 'a> {
|
||||||
tcx: &'a ty::ctxt<'tcx>,
|
tcx: &'a ty::ctxt<'tcx>,
|
||||||
active_features: FnvHashSet<InternedString>,
|
active_features: FnvHashSet<InternedString>,
|
||||||
used_features: FnvHashMap<InternedString, attr::StabilityLevel>,
|
used_features: FnvHashMap<InternedString, StabilityLevel>,
|
||||||
// Within a block where feature gate checking can be skipped.
|
// Within a block where feature gate checking can be skipped.
|
||||||
in_skip_block: u32,
|
in_skip_block: u32,
|
||||||
}
|
}
|
||||||
@ -303,8 +316,8 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match *stab {
|
match *stab {
|
||||||
Some(&Stability { level: attr::Unstable, ref feature, ref reason, issue, .. }) => {
|
Some(&Stability { level: attr::Unstable {ref reason, issue}, ref feature, .. }) => {
|
||||||
self.used_features.insert(feature.clone(), attr::Unstable);
|
self.used_features.insert(feature.clone(), Unstable);
|
||||||
|
|
||||||
if !self.active_features.contains(feature) {
|
if !self.active_features.contains(feature) {
|
||||||
let msg = match *reason {
|
let msg = match *reason {
|
||||||
@ -312,13 +325,12 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||||||
&feature, &r),
|
&feature, &r),
|
||||||
None => format!("use of unstable library feature '{}'", &feature)
|
None => format!("use of unstable library feature '{}'", &feature)
|
||||||
};
|
};
|
||||||
|
|
||||||
emit_feature_err(&self.tcx.sess.parse_sess.span_diagnostic,
|
emit_feature_err(&self.tcx.sess.parse_sess.span_diagnostic,
|
||||||
&feature, span, GateIssue::Library(issue), &msg);
|
&feature, span, GateIssue::Library(Some(issue)), &msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(&Stability { level, ref feature, .. }) => {
|
Some(&Stability { ref level, ref feature, .. }) => {
|
||||||
self.used_features.insert(feature.clone(), level);
|
self.used_features.insert(feature.clone(), StabilityLevel::from_attr_level(level));
|
||||||
|
|
||||||
// Stable APIs are always ok to call and deprecated APIs are
|
// Stable APIs are always ok to call and deprecated APIs are
|
||||||
// handled by a lint.
|
// handled by a lint.
|
||||||
@ -636,7 +648,7 @@ fn lookup_uncached<'tcx>(tcx: &ty::ctxt<'tcx>, id: DefId) -> Option<&'tcx Stabil
|
|||||||
/// libraries, identify activated features that don't exist and error about them.
|
/// libraries, identify activated features that don't exist and error about them.
|
||||||
pub fn check_unused_or_stable_features(sess: &Session,
|
pub fn check_unused_or_stable_features(sess: &Session,
|
||||||
lib_features_used: &FnvHashMap<InternedString,
|
lib_features_used: &FnvHashMap<InternedString,
|
||||||
attr::StabilityLevel>) {
|
StabilityLevel>) {
|
||||||
let ref declared_lib_features = sess.features.borrow().declared_lib_features;
|
let ref declared_lib_features = sess.features.borrow().declared_lib_features;
|
||||||
let mut remaining_lib_features: FnvHashMap<InternedString, Span>
|
let mut remaining_lib_features: FnvHashMap<InternedString, Span>
|
||||||
= declared_lib_features.clone().into_iter().collect();
|
= declared_lib_features.clone().into_iter().collect();
|
||||||
@ -653,7 +665,7 @@ pub fn check_unused_or_stable_features(sess: &Session,
|
|||||||
for (used_lib_feature, level) in lib_features_used {
|
for (used_lib_feature, level) in lib_features_used {
|
||||||
match remaining_lib_features.remove(used_lib_feature) {
|
match remaining_lib_features.remove(used_lib_feature) {
|
||||||
Some(span) => {
|
Some(span) => {
|
||||||
if *level == attr::Stable {
|
if *level == Stable {
|
||||||
sess.add_lint(lint::builtin::STABLE_FEATURES,
|
sess.add_lint(lint::builtin::STABLE_FEATURES,
|
||||||
ast::CRATE_NODE_ID,
|
ast::CRATE_NODE_ID,
|
||||||
span,
|
span,
|
||||||
|
@ -1,625 +0,0 @@
|
|||||||
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
// Functions dealing with attributes and meta items
|
|
||||||
|
|
||||||
pub use self::StabilityLevel::*;
|
|
||||||
pub use self::ReprAttr::*;
|
|
||||||
pub use self::IntType::*;
|
|
||||||
|
|
||||||
use hir;
|
|
||||||
use syntax::codemap::{Span, Spanned, spanned, dummy_spanned};
|
|
||||||
use syntax::codemap::BytePos;
|
|
||||||
use syntax::diagnostic::SpanHandler;
|
|
||||||
use syntax::attr as syntax_attr;
|
|
||||||
use syntax::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
|
|
||||||
use syntax::parse::token::{InternedString, intern_and_get_ident};
|
|
||||||
use syntax::parse::token;
|
|
||||||
use syntax::ptr::P;
|
|
||||||
|
|
||||||
use std::cell::Cell;
|
|
||||||
use std::collections::HashSet;
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
pub fn mark_used(attr: &Attribute) {
|
|
||||||
syntax_attr::mark_used(&unlower_attribute(attr))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait AttrMetaMethods {
|
|
||||||
fn check_name(&self, name: &str) -> bool {
|
|
||||||
name == &self.name()[..]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieve the name of the meta item, e.g. `foo` in `#[foo]`,
|
|
||||||
/// `#[foo="bar"]` and `#[foo(bar)]`
|
|
||||||
fn name(&self) -> InternedString;
|
|
||||||
|
|
||||||
/// Gets the string value if self is a MetaNameValue variant
|
|
||||||
/// containing a string, otherwise None.
|
|
||||||
fn value_str(&self) -> Option<InternedString>;
|
|
||||||
/// Gets a list of inner meta items from a list MetaItem type.
|
|
||||||
fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]>;
|
|
||||||
|
|
||||||
fn span(&self) -> Span;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AttrMetaMethods for Attribute {
|
|
||||||
fn check_name(&self, name: &str) -> bool {
|
|
||||||
let matches = name == &self.name()[..];
|
|
||||||
if matches {
|
|
||||||
syntax_attr::mark_used(&unlower_attribute(self));
|
|
||||||
}
|
|
||||||
matches
|
|
||||||
}
|
|
||||||
fn name(&self) -> InternedString { self.meta().name() }
|
|
||||||
fn value_str(&self) -> Option<InternedString> {
|
|
||||||
self.meta().value_str()
|
|
||||||
}
|
|
||||||
fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]> {
|
|
||||||
self.node.value.meta_item_list()
|
|
||||||
}
|
|
||||||
fn span(&self) -> Span { self.meta().span }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AttrMetaMethods for MetaItem {
|
|
||||||
fn name(&self) -> InternedString {
|
|
||||||
match self.node {
|
|
||||||
MetaWord(ref n) => (*n).clone(),
|
|
||||||
MetaNameValue(ref n, _) => (*n).clone(),
|
|
||||||
MetaList(ref n, _) => (*n).clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn value_str(&self) -> Option<InternedString> {
|
|
||||||
match self.node {
|
|
||||||
MetaNameValue(_, ref v) => {
|
|
||||||
match v.node {
|
|
||||||
hir::LitStr(ref s, _) => Some((*s).clone()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]> {
|
|
||||||
match self.node {
|
|
||||||
MetaList(_, ref l) => Some(&l[..]),
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn span(&self) -> Span { self.span }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Annoying, but required to get test_cfg to work
|
|
||||||
impl AttrMetaMethods for P<MetaItem> {
|
|
||||||
fn name(&self) -> InternedString { (**self).name() }
|
|
||||||
fn value_str(&self) -> Option<InternedString> { (**self).value_str() }
|
|
||||||
fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]> {
|
|
||||||
(**self).meta_item_list()
|
|
||||||
}
|
|
||||||
fn span(&self) -> Span { (**self).span() }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub trait AttributeMethods {
|
|
||||||
fn meta<'a>(&'a self) -> &'a MetaItem;
|
|
||||||
fn with_desugared_doc<T, F>(&self, f: F) -> T where
|
|
||||||
F: FnOnce(&Attribute) -> T;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AttributeMethods for Attribute {
|
|
||||||
/// Extract the MetaItem from inside this Attribute.
|
|
||||||
fn meta<'a>(&'a self) -> &'a MetaItem {
|
|
||||||
&*self.node.value
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert self to a normal #[doc="foo"] comment, if it is a
|
|
||||||
/// comment like `///` or `/** */`. (Returns self unchanged for
|
|
||||||
/// non-sugared doc attributes.)
|
|
||||||
fn with_desugared_doc<T, F>(&self, f: F) -> T where
|
|
||||||
F: FnOnce(&Attribute) -> T,
|
|
||||||
{
|
|
||||||
if self.node.is_sugared_doc {
|
|
||||||
let comment = self.value_str().unwrap();
|
|
||||||
let meta = mk_name_value_item_str(
|
|
||||||
InternedString::new("doc"),
|
|
||||||
token::intern_and_get_ident(&strip_doc_comment_decoration(
|
|
||||||
&comment)));
|
|
||||||
if self.node.style == hir::AttrOuter {
|
|
||||||
f(&mk_attr_outer(self.node.id, meta))
|
|
||||||
} else {
|
|
||||||
f(&mk_attr_inner(self.node.id, meta))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
f(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Constructors */
|
|
||||||
|
|
||||||
pub fn mk_name_value_item_str(name: InternedString, value: InternedString)
|
|
||||||
-> P<MetaItem> {
|
|
||||||
let value_lit = dummy_spanned(hir::LitStr(value, hir::CookedStr));
|
|
||||||
mk_name_value_item(name, value_lit)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mk_name_value_item(name: InternedString, value: hir::Lit)
|
|
||||||
-> P<MetaItem> {
|
|
||||||
P(dummy_spanned(MetaNameValue(name, value)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mk_list_item(name: InternedString, items: Vec<P<MetaItem>>) -> P<MetaItem> {
|
|
||||||
P(dummy_spanned(MetaList(name, items)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mk_word_item(name: InternedString) -> P<MetaItem> {
|
|
||||||
P(dummy_spanned(MetaWord(name)))
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_local! { static NEXT_ATTR_ID: Cell<usize> = Cell::new(0) }
|
|
||||||
|
|
||||||
pub fn mk_attr_id() -> AttrId {
|
|
||||||
let id = NEXT_ATTR_ID.with(|slot| {
|
|
||||||
let r = slot.get();
|
|
||||||
slot.set(r + 1);
|
|
||||||
r
|
|
||||||
});
|
|
||||||
AttrId(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an inner attribute with the given value.
|
|
||||||
pub fn mk_attr_inner(id: AttrId, item: P<MetaItem>) -> Attribute {
|
|
||||||
dummy_spanned(Attribute_ {
|
|
||||||
id: id,
|
|
||||||
style: hir::AttrStyle::Inner,
|
|
||||||
value: item,
|
|
||||||
is_sugared_doc: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an outer attribute with the given value.
|
|
||||||
pub fn mk_attr_outer(id: AttrId, item: P<MetaItem>) -> Attribute {
|
|
||||||
dummy_spanned(Attribute_ {
|
|
||||||
id: id,
|
|
||||||
style: hir::AttrStyle::Outer,
|
|
||||||
value: item,
|
|
||||||
is_sugared_doc: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mk_sugared_doc_attr(id: AttrId, text: InternedString, lo: BytePos,
|
|
||||||
hi: BytePos)
|
|
||||||
-> Attribute {
|
|
||||||
let style = lower_attr_style(doc_comment_style(&text));
|
|
||||||
let lit = spanned(lo, hi, hir::LitStr(text, hir::CookedStr));
|
|
||||||
let attr = Attribute_ {
|
|
||||||
id: id,
|
|
||||||
style: style,
|
|
||||||
value: P(spanned(lo, hi, MetaNameValue(InternedString::new("doc"),
|
|
||||||
lit))),
|
|
||||||
is_sugared_doc: true
|
|
||||||
};
|
|
||||||
spanned(lo, hi, attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Searching */
|
|
||||||
/// Check if `needle` occurs in `haystack` by a structural
|
|
||||||
/// comparison. This is slightly subtle, and relies on ignoring the
|
|
||||||
/// span included in the `==` comparison a plain MetaItem.
|
|
||||||
pub fn contains(haystack: &[P<MetaItem>], needle: &MetaItem) -> bool {
|
|
||||||
debug!("attr::contains (name={})", needle.name());
|
|
||||||
haystack.iter().any(|item| {
|
|
||||||
debug!(" testing: {}", item.name());
|
|
||||||
item.node == needle.node
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn contains_name<AM: AttrMetaMethods>(metas: &[AM], name: &str) -> bool {
|
|
||||||
debug!("attr::contains_name (name={})", name);
|
|
||||||
metas.iter().any(|item| {
|
|
||||||
debug!(" testing: {}", item.name());
|
|
||||||
item.check_name(name)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str)
|
|
||||||
-> Option<InternedString> {
|
|
||||||
attrs.iter()
|
|
||||||
.find(|at| at.check_name(name))
|
|
||||||
.and_then(|at| at.value_str())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn last_meta_item_value_str_by_name(items: &[P<MetaItem>], name: &str)
|
|
||||||
-> Option<InternedString> {
|
|
||||||
items.iter()
|
|
||||||
.rev()
|
|
||||||
.find(|mi| mi.check_name(name))
|
|
||||||
.and_then(|i| i.value_str())
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Higher-level applications */
|
|
||||||
|
|
||||||
pub fn sort_meta_items(items: Vec<P<MetaItem>>) -> Vec<P<MetaItem>> {
|
|
||||||
// This is sort of stupid here, but we need to sort by
|
|
||||||
// human-readable strings.
|
|
||||||
let mut v = items.into_iter()
|
|
||||||
.map(|mi| (mi.name(), mi))
|
|
||||||
.collect::<Vec<(InternedString, P<MetaItem>)>>();
|
|
||||||
|
|
||||||
v.sort_by(|&(ref a, _), &(ref b, _)| a.cmp(b));
|
|
||||||
|
|
||||||
// There doesn't seem to be a more optimal way to do this
|
|
||||||
v.into_iter().map(|(_, m)| m.map(|Spanned {node, span}| {
|
|
||||||
Spanned {
|
|
||||||
node: match node {
|
|
||||||
MetaList(n, mis) => MetaList(n, sort_meta_items(mis)),
|
|
||||||
_ => node
|
|
||||||
},
|
|
||||||
span: span
|
|
||||||
}
|
|
||||||
})).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> {
|
|
||||||
first_attr_value_str_by_name(attrs, "crate_name")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Find the value of #[export_name=*] attribute and check its validity.
|
|
||||||
pub fn find_export_name_attr(diag: &SpanHandler, attrs: &[Attribute]) -> Option<InternedString> {
|
|
||||||
attrs.iter().fold(None, |ia,attr| {
|
|
||||||
if attr.check_name("export_name") {
|
|
||||||
if let s@Some(_) = attr.value_str() {
|
|
||||||
s
|
|
||||||
} else {
|
|
||||||
diag.span_err(attr.span, "export_name attribute has invalid format");
|
|
||||||
diag.handler.help("use #[export_name=\"*\"]");
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ia
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
|
||||||
pub enum InlineAttr {
|
|
||||||
None,
|
|
||||||
Hint,
|
|
||||||
Always,
|
|
||||||
Never,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determine what `#[inline]` attribute is present in `attrs`, if any.
|
|
||||||
pub fn find_inline_attr(diagnostic: Option<&SpanHandler>, attrs: &[Attribute]) -> InlineAttr {
|
|
||||||
attrs.iter().fold(InlineAttr::None, |ia,attr| {
|
|
||||||
match attr.node.value.node {
|
|
||||||
MetaWord(ref n) if *n == "inline" => {
|
|
||||||
syntax_attr::mark_used(&unlower_attribute(attr));
|
|
||||||
InlineAttr::Hint
|
|
||||||
}
|
|
||||||
MetaList(ref n, ref items) if *n == "inline" => {
|
|
||||||
syntax_attr::mark_used(&unlower_attribute(attr));
|
|
||||||
if items.len() != 1 {
|
|
||||||
diagnostic.map(|d|{ d.span_err(attr.span, "expected one argument"); });
|
|
||||||
InlineAttr::None
|
|
||||||
} else if contains_name(&items[..], "always") {
|
|
||||||
InlineAttr::Always
|
|
||||||
} else if contains_name(&items[..], "never") {
|
|
||||||
InlineAttr::Never
|
|
||||||
} else {
|
|
||||||
diagnostic.map(|d|{ d.span_err((*items[0]).span, "invalid argument"); });
|
|
||||||
InlineAttr::None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => ia
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// True if `#[inline]` or `#[inline(always)]` is present in `attrs`.
|
|
||||||
pub fn requests_inline(attrs: &[Attribute]) -> bool {
|
|
||||||
match find_inline_attr(None, attrs) {
|
|
||||||
InlineAttr::Hint | InlineAttr::Always => true,
|
|
||||||
InlineAttr::None | InlineAttr::Never => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents the #[deprecated] and friends attributes.
|
|
||||||
#[derive(RustcEncodable, RustcDecodable, Clone, Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub struct Stability {
|
|
||||||
pub level: StabilityLevel,
|
|
||||||
pub feature: InternedString,
|
|
||||||
pub since: Option<InternedString>,
|
|
||||||
pub deprecated_since: Option<InternedString>,
|
|
||||||
// The reason for the current stability level. If deprecated, the
|
|
||||||
// reason for deprecation.
|
|
||||||
pub reason: Option<InternedString>,
|
|
||||||
// The relevant rust-lang issue
|
|
||||||
pub issue: Option<u32>
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The available stability levels.
|
|
||||||
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Copy, Eq, Hash)]
|
|
||||||
pub enum StabilityLevel {
|
|
||||||
Unstable,
|
|
||||||
Stable,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for StabilityLevel {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_stability_generic<'a,
|
|
||||||
AM: AttrMetaMethods,
|
|
||||||
I: Iterator<Item=&'a AM>>
|
|
||||||
(diagnostic: &SpanHandler, attrs: I, item_sp: Span)
|
|
||||||
-> (Option<Stability>, Vec<&'a AM>) {
|
|
||||||
|
|
||||||
let mut stab: Option<Stability> = None;
|
|
||||||
let mut deprecated: Option<(Option<InternedString>, Option<InternedString>)> = None;
|
|
||||||
let mut used_attrs: Vec<&'a AM> = vec![];
|
|
||||||
|
|
||||||
'outer: for attr in attrs {
|
|
||||||
let tag = attr.name();
|
|
||||||
let tag = &tag[..];
|
|
||||||
if tag != "deprecated" && tag != "unstable" && tag != "stable" {
|
|
||||||
continue // not a stability level
|
|
||||||
}
|
|
||||||
|
|
||||||
used_attrs.push(attr);
|
|
||||||
|
|
||||||
let (feature, since, reason, issue) = match attr.meta_item_list() {
|
|
||||||
Some(metas) => {
|
|
||||||
let mut feature = None;
|
|
||||||
let mut since = None;
|
|
||||||
let mut reason = None;
|
|
||||||
let mut issue = None;
|
|
||||||
for meta in metas {
|
|
||||||
match &*meta.name() {
|
|
||||||
"feature" => {
|
|
||||||
match meta.value_str() {
|
|
||||||
Some(v) => feature = Some(v),
|
|
||||||
None => {
|
|
||||||
diagnostic.span_err(meta.span, "incorrect meta item");
|
|
||||||
continue 'outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"since" => {
|
|
||||||
match meta.value_str() {
|
|
||||||
Some(v) => since = Some(v),
|
|
||||||
None => {
|
|
||||||
diagnostic.span_err(meta.span, "incorrect meta item");
|
|
||||||
continue 'outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"reason" => {
|
|
||||||
match meta.value_str() {
|
|
||||||
Some(v) => reason = Some(v),
|
|
||||||
None => {
|
|
||||||
diagnostic.span_err(meta.span, "incorrect meta item");
|
|
||||||
continue 'outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"issue" => {
|
|
||||||
match meta.value_str().and_then(|s| s.parse().ok()) {
|
|
||||||
Some(v) => issue = Some(v),
|
|
||||||
None => {
|
|
||||||
diagnostic.span_err(meta.span, "incorrect meta item");
|
|
||||||
continue 'outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(feature, since, reason, issue)
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
diagnostic.span_err(attr.span(), "incorrect stability attribute type");
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Deprecated tags don't require feature names
|
|
||||||
if feature == None && tag != "deprecated" {
|
|
||||||
diagnostic.span_err(attr.span(), "missing 'feature'");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unstable tags don't require a version
|
|
||||||
if since == None && tag != "unstable" {
|
|
||||||
diagnostic.span_err(attr.span(), "missing 'since'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if tag == "unstable" || tag == "stable" {
|
|
||||||
if stab.is_some() {
|
|
||||||
diagnostic.span_err(item_sp, "multiple stability levels");
|
|
||||||
}
|
|
||||||
|
|
||||||
let level = match tag {
|
|
||||||
"unstable" => Unstable,
|
|
||||||
"stable" => Stable,
|
|
||||||
_ => unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
stab = Some(Stability {
|
|
||||||
level: level,
|
|
||||||
feature: feature.unwrap_or(intern_and_get_ident("bogus")),
|
|
||||||
since: since,
|
|
||||||
deprecated_since: None,
|
|
||||||
reason: reason,
|
|
||||||
issue: issue,
|
|
||||||
});
|
|
||||||
} else { // "deprecated"
|
|
||||||
if deprecated.is_some() {
|
|
||||||
diagnostic.span_err(item_sp, "multiple deprecated attributes");
|
|
||||||
}
|
|
||||||
|
|
||||||
deprecated = Some((since, reason));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merge the deprecation info into the stability info
|
|
||||||
if deprecated.is_some() {
|
|
||||||
match stab {
|
|
||||||
Some(ref mut s) => {
|
|
||||||
let (since, reason) = deprecated.unwrap();
|
|
||||||
s.deprecated_since = since;
|
|
||||||
s.reason = reason;
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
diagnostic.span_err(item_sp, "deprecated attribute must be paired with \
|
|
||||||
either stable or unstable attribute");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if stab.as_ref().map_or(false, |s| s.level == Unstable && s.issue.is_none()) {
|
|
||||||
// non-deprecated unstable items need to point to issues.
|
|
||||||
diagnostic.span_err(item_sp,
|
|
||||||
"non-deprecated unstable items need to point \
|
|
||||||
to an issue with `issue = \"NNN\"`");
|
|
||||||
}
|
|
||||||
|
|
||||||
(stab, used_attrs)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Find the first stability attribute. `None` if none exists.
|
|
||||||
pub fn find_stability(diagnostic: &SpanHandler, attrs: &[Attribute],
|
|
||||||
item_sp: Span) -> Option<Stability> {
|
|
||||||
let (s, used) = find_stability_generic(diagnostic, attrs.iter(), item_sp);
|
|
||||||
for used in used { syntax_attr::mark_used(&unlower_attribute(used)) }
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P<MetaItem>]) {
|
|
||||||
let mut set = HashSet::new();
|
|
||||||
for meta in metas {
|
|
||||||
let name = meta.name();
|
|
||||||
|
|
||||||
if !set.insert(name.clone()) {
|
|
||||||
panic!(diagnostic.span_fatal(meta.span,
|
|
||||||
&format!("duplicate meta item `{}`", name)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Parse #[repr(...)] forms.
|
|
||||||
///
|
|
||||||
/// Valid repr contents: any of the primitive integral type names (see
|
|
||||||
/// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use
|
|
||||||
/// the same discriminant size that the corresponding C enum would or C
|
|
||||||
/// structure layout, and `packed` to remove padding.
|
|
||||||
pub fn find_repr_attrs(diagnostic: &SpanHandler, attr: &Attribute) -> Vec<ReprAttr> {
|
|
||||||
let mut acc = Vec::new();
|
|
||||||
match attr.node.value.node {
|
|
||||||
hir::MetaList(ref s, ref items) if *s == "repr" => {
|
|
||||||
syntax_attr::mark_used(&unlower_attribute(attr));
|
|
||||||
for item in items {
|
|
||||||
match item.node {
|
|
||||||
hir::MetaWord(ref word) => {
|
|
||||||
let hint = match &word[..] {
|
|
||||||
// Can't use "extern" because it's not a lexical identifier.
|
|
||||||
"C" => Some(ReprExtern),
|
|
||||||
"packed" => Some(ReprPacked),
|
|
||||||
"simd" => Some(ReprSimd),
|
|
||||||
_ => match int_type_of_word(&word) {
|
|
||||||
Some(ity) => Some(ReprInt(item.span, ity)),
|
|
||||||
None => {
|
|
||||||
// Not a word we recognize
|
|
||||||
diagnostic.span_err(item.span,
|
|
||||||
"unrecognized representation hint");
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match hint {
|
|
||||||
Some(h) => acc.push(h),
|
|
||||||
None => { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Not a word:
|
|
||||||
_ => diagnostic.span_err(item.span, "unrecognized enum representation hint")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Not a "repr" hint: ignore.
|
|
||||||
_ => { }
|
|
||||||
}
|
|
||||||
acc
|
|
||||||
}
|
|
||||||
|
|
||||||
fn int_type_of_word(s: &str) -> Option<IntType> {
|
|
||||||
match s {
|
|
||||||
"i8" => Some(SignedInt(hir::TyI8)),
|
|
||||||
"u8" => Some(UnsignedInt(hir::TyU8)),
|
|
||||||
"i16" => Some(SignedInt(hir::TyI16)),
|
|
||||||
"u16" => Some(UnsignedInt(hir::TyU16)),
|
|
||||||
"i32" => Some(SignedInt(hir::TyI32)),
|
|
||||||
"u32" => Some(UnsignedInt(hir::TyU32)),
|
|
||||||
"i64" => Some(SignedInt(hir::TyI64)),
|
|
||||||
"u64" => Some(UnsignedInt(hir::TyU64)),
|
|
||||||
"isize" => Some(SignedInt(hir::TyIs)),
|
|
||||||
"usize" => Some(UnsignedInt(hir::TyUs)),
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
|
|
||||||
pub enum ReprAttr {
|
|
||||||
ReprAny,
|
|
||||||
ReprInt(Span, IntType),
|
|
||||||
ReprExtern,
|
|
||||||
ReprPacked,
|
|
||||||
ReprSimd,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ReprAttr {
|
|
||||||
pub fn is_ffi_safe(&self) -> bool {
|
|
||||||
match *self {
|
|
||||||
ReprAny => false,
|
|
||||||
ReprInt(_sp, ity) => ity.is_ffi_safe(),
|
|
||||||
ReprExtern => true,
|
|
||||||
ReprPacked => false,
|
|
||||||
ReprSimd => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Eq, Hash, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
|
|
||||||
pub enum IntType {
|
|
||||||
SignedInt(hir::IntTy),
|
|
||||||
UnsignedInt(hir::UintTy)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntType {
|
|
||||||
#[inline]
|
|
||||||
pub fn is_signed(self) -> bool {
|
|
||||||
match self {
|
|
||||||
SignedInt(..) => true,
|
|
||||||
UnsignedInt(..) => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn is_ffi_safe(self) -> bool {
|
|
||||||
match self {
|
|
||||||
SignedInt(hir::TyI8) | UnsignedInt(hir::TyU8) |
|
|
||||||
SignedInt(hir::TyI16) | UnsignedInt(hir::TyU16) |
|
|
||||||
SignedInt(hir::TyI32) | UnsignedInt(hir::TyU32) |
|
|
||||||
SignedInt(hir::TyI64) | UnsignedInt(hir::TyU64) => true,
|
|
||||||
SignedInt(hir::TyIs) | UnsignedInt(hir::TyUs) => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -674,7 +674,7 @@ impl Stability {
|
|||||||
span: Span, stability: &Option<&attr::Stability>) {
|
span: Span, stability: &Option<&attr::Stability>) {
|
||||||
// Deprecated attributes apply in-crate and cross-crate.
|
// Deprecated attributes apply in-crate and cross-crate.
|
||||||
let (lint, label) = match *stability {
|
let (lint, label) = match *stability {
|
||||||
Some(&attr::Stability { deprecated_since: Some(_), .. }) =>
|
Some(&attr::Stability { depr: Some(_), .. }) =>
|
||||||
(DEPRECATED, "deprecated"),
|
(DEPRECATED, "deprecated"),
|
||||||
_ => return
|
_ => return
|
||||||
};
|
};
|
||||||
@ -684,8 +684,8 @@ impl Stability {
|
|||||||
fn output(cx: &LateContext, span: Span, stability: &Option<&attr::Stability>,
|
fn output(cx: &LateContext, span: Span, stability: &Option<&attr::Stability>,
|
||||||
lint: &'static Lint, label: &'static str) {
|
lint: &'static Lint, label: &'static str) {
|
||||||
let msg = match *stability {
|
let msg = match *stability {
|
||||||
Some(&attr::Stability { reason: Some(ref s), .. }) => {
|
Some(&attr::Stability {depr: Some(attr::Deprecation {ref reason, ..}), ..}) => {
|
||||||
format!("use of {} item: {}", label, *s)
|
format!("use of {} item: {}", label, reason)
|
||||||
}
|
}
|
||||||
_ => format!("use of {} item", label)
|
_ => format!("use of {} item", label)
|
||||||
};
|
};
|
||||||
@ -695,20 +695,6 @@ impl Stability {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hir_to_ast_stability(stab: &attr::Stability) -> attr::Stability {
|
|
||||||
attr::Stability {
|
|
||||||
level: match stab.level {
|
|
||||||
attr::Unstable => attr::Unstable,
|
|
||||||
attr::Stable => attr::Stable,
|
|
||||||
},
|
|
||||||
feature: stab.feature.clone(),
|
|
||||||
since: stab.since.clone(),
|
|
||||||
deprecated_since: stab.deprecated_since.clone(),
|
|
||||||
reason: stab.reason.clone(),
|
|
||||||
issue: stab.issue,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LintPass for Stability {
|
impl LintPass for Stability {
|
||||||
fn get_lints(&self) -> LintArray {
|
fn get_lints(&self) -> LintArray {
|
||||||
lint_array!(DEPRECATED)
|
lint_array!(DEPRECATED)
|
||||||
@ -719,36 +705,31 @@ impl LateLintPass for Stability {
|
|||||||
fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
|
fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
|
||||||
stability::check_item(cx.tcx, item, false,
|
stability::check_item(cx.tcx, item, false,
|
||||||
&mut |id, sp, stab|
|
&mut |id, sp, stab|
|
||||||
self.lint(cx, id, sp,
|
self.lint(cx, id, sp, &stab));
|
||||||
&stab.map(|s| hir_to_ast_stability(s)).as_ref()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
|
fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
|
||||||
stability::check_expr(cx.tcx, e,
|
stability::check_expr(cx.tcx, e,
|
||||||
&mut |id, sp, stab|
|
&mut |id, sp, stab|
|
||||||
self.lint(cx, id, sp,
|
self.lint(cx, id, sp, &stab));
|
||||||
&stab.map(|s| hir_to_ast_stability(s)).as_ref()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_path(&mut self, cx: &LateContext, path: &hir::Path, id: ast::NodeId) {
|
fn check_path(&mut self, cx: &LateContext, path: &hir::Path, id: ast::NodeId) {
|
||||||
stability::check_path(cx.tcx, path, id,
|
stability::check_path(cx.tcx, path, id,
|
||||||
&mut |id, sp, stab|
|
&mut |id, sp, stab|
|
||||||
self.lint(cx, id, sp,
|
self.lint(cx, id, sp, &stab));
|
||||||
&stab.map(|s| hir_to_ast_stability(s)).as_ref()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_path_list_item(&mut self, cx: &LateContext, item: &hir::PathListItem) {
|
fn check_path_list_item(&mut self, cx: &LateContext, item: &hir::PathListItem) {
|
||||||
stability::check_path_list_item(cx.tcx, item,
|
stability::check_path_list_item(cx.tcx, item,
|
||||||
&mut |id, sp, stab|
|
&mut |id, sp, stab|
|
||||||
self.lint(cx, id, sp,
|
self.lint(cx, id, sp, &stab));
|
||||||
&stab.map(|s| hir_to_ast_stability(s)).as_ref()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_pat(&mut self, cx: &LateContext, pat: &hir::Pat) {
|
fn check_pat(&mut self, cx: &LateContext, pat: &hir::Pat) {
|
||||||
stability::check_pat(cx.tcx, pat,
|
stability::check_pat(cx.tcx, pat,
|
||||||
&mut |id, sp, stab|
|
&mut |id, sp, stab|
|
||||||
self.lint(cx, id, sp,
|
self.lint(cx, id, sp, &stab));
|
||||||
&stab.map(|s| hir_to_ast_stability(s)).as_ref()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,8 +324,8 @@ impl Item {
|
|||||||
match self.stability {
|
match self.stability {
|
||||||
Some(ref s) => {
|
Some(ref s) => {
|
||||||
let mut base = match s.level {
|
let mut base = match s.level {
|
||||||
attr::Unstable => "unstable".to_string(),
|
stability::Unstable => "unstable".to_string(),
|
||||||
attr::Stable => String::new(),
|
stability::Stable => String::new(),
|
||||||
};
|
};
|
||||||
if !s.deprecated_since.is_empty() {
|
if !s.deprecated_since.is_empty() {
|
||||||
base.push_str(" deprecated");
|
base.push_str(" deprecated");
|
||||||
@ -2679,7 +2679,7 @@ impl Clean<Item> for doctree::Macro {
|
|||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub struct Stability {
|
pub struct Stability {
|
||||||
pub level: attr::StabilityLevel,
|
pub level: stability::StabilityLevel,
|
||||||
pub feature: String,
|
pub feature: String,
|
||||||
pub since: String,
|
pub since: String,
|
||||||
pub deprecated_since: String,
|
pub deprecated_since: String,
|
||||||
@ -2690,32 +2690,31 @@ pub struct Stability {
|
|||||||
impl Clean<Stability> for attr::Stability {
|
impl Clean<Stability> for attr::Stability {
|
||||||
fn clean(&self, _: &DocContext) -> Stability {
|
fn clean(&self, _: &DocContext) -> Stability {
|
||||||
Stability {
|
Stability {
|
||||||
level: self.level,
|
level: stability::StabilityLevel::from_attr_level(&self.level),
|
||||||
feature: self.feature.to_string(),
|
feature: self.feature.to_string(),
|
||||||
since: self.since.as_ref().map_or("".to_string(),
|
since: match self.level {
|
||||||
|interned| interned.to_string()),
|
attr::Stable {ref since} => since.to_string(),
|
||||||
deprecated_since: self.deprecated_since.as_ref().map_or("".to_string(),
|
_ => "".to_string(),
|
||||||
|istr| istr.to_string()),
|
},
|
||||||
reason: self.reason.as_ref().map_or("".to_string(),
|
deprecated_since: match self.depr {
|
||||||
|interned| interned.to_string()),
|
Some(attr::Deprecation {ref since, ..}) => since.to_string(),
|
||||||
issue: self.issue,
|
_=> "".to_string(),
|
||||||
|
},
|
||||||
|
reason: match self.level {
|
||||||
|
attr::Unstable {reason: Some(ref reason), ..} => reason.to_string(),
|
||||||
|
_ => "".to_string(),
|
||||||
|
},
|
||||||
|
issue: match self.level {
|
||||||
|
attr::Unstable {issue, ..} => Some(issue),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Clean<Stability> for &'a attr::Stability {
|
impl<'a> Clean<Stability> for &'a attr::Stability {
|
||||||
fn clean(&self, _: &DocContext) -> Stability {
|
fn clean(&self, dc: &DocContext) -> Stability {
|
||||||
Stability {
|
(**self).clean(dc)
|
||||||
level: self.level,
|
|
||||||
feature: self.feature.to_string(),
|
|
||||||
since: self.since.as_ref().map_or("".to_string(),
|
|
||||||
|interned| interned.to_string()),
|
|
||||||
deprecated_since: self.deprecated_since.as_ref().map_or("".to_string(),
|
|
||||||
|istr| istr.to_string()),
|
|
||||||
reason: self.reason.as_ref().map_or("".to_string(),
|
|
||||||
|interned| interned.to_string()),
|
|
||||||
issue: self.issue,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,9 +52,10 @@ use std::sync::Arc;
|
|||||||
use externalfiles::ExternalHtml;
|
use externalfiles::ExternalHtml;
|
||||||
|
|
||||||
use serialize::json::{self, ToJson};
|
use serialize::json::{self, ToJson};
|
||||||
use syntax::{abi, ast, attr};
|
use syntax::{abi, ast};
|
||||||
use rustc::metadata::cstore::LOCAL_CRATE;
|
use rustc::metadata::cstore::LOCAL_CRATE;
|
||||||
use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
|
use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
|
||||||
|
use rustc::middle::stability;
|
||||||
use rustc::util::nodemap::DefIdSet;
|
use rustc::util::nodemap::DefIdSet;
|
||||||
use rustc_front::hir;
|
use rustc_front::hir;
|
||||||
|
|
||||||
@ -1608,8 +1609,8 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||||||
let s1 = i1.stability.as_ref().map(|s| s.level);
|
let s1 = i1.stability.as_ref().map(|s| s.level);
|
||||||
let s2 = i2.stability.as_ref().map(|s| s.level);
|
let s2 = i2.stability.as_ref().map(|s| s.level);
|
||||||
match (s1, s2) {
|
match (s1, s2) {
|
||||||
(Some(attr::Unstable), Some(attr::Stable)) => return Ordering::Greater,
|
(Some(stability::Unstable), Some(stability::Stable)) => return Ordering::Greater,
|
||||||
(Some(attr::Stable), Some(attr::Unstable)) => return Ordering::Less,
|
(Some(stability::Stable), Some(stability::Unstable)) => return Ordering::Less,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
i1.name.cmp(&i2.name)
|
i1.name.cmp(&i2.name)
|
||||||
@ -1724,7 +1725,7 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Optio
|
|||||||
String::new()
|
String::new()
|
||||||
};
|
};
|
||||||
format!("Deprecated{}{}", since, Markdown(&reason))
|
format!("Deprecated{}{}", since, Markdown(&reason))
|
||||||
} else if stab.level == attr::Unstable {
|
} else if stab.level == stability::Unstable {
|
||||||
let unstable_extra = if show_reason {
|
let unstable_extra = if show_reason {
|
||||||
match (!stab.feature.is_empty(), &cx.issue_tracker_base_url, stab.issue) {
|
match (!stab.feature.is_empty(), &cx.issue_tracker_base_url, stab.issue) {
|
||||||
(true, &Some(ref tracker_url), Some(issue_no)) =>
|
(true, &Some(ref tracker_url), Some(issue_no)) =>
|
||||||
|
@ -27,7 +27,6 @@ use ptr::P;
|
|||||||
|
|
||||||
use std::cell::{RefCell, Cell};
|
use std::cell::{RefCell, Cell};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static USED_ATTRS: RefCell<Vec<u64>> = RefCell::new(Vec::new())
|
static USED_ATTRS: RefCell<Vec<u64>> = RefCell::new(Vec::new())
|
||||||
@ -382,174 +381,223 @@ pub fn cfg_matches(diagnostic: &SpanHandler, cfgs: &[P<MetaItem>], cfg: &ast::Me
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the #[deprecated] and friends attributes.
|
/// Represents the #[stable], #[unstable] and #[deprecated] attributes.
|
||||||
#[derive(RustcEncodable, RustcDecodable, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(RustcEncodable, RustcDecodable, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct Stability {
|
pub struct Stability {
|
||||||
pub level: StabilityLevel,
|
pub level: StabilityLevel,
|
||||||
pub feature: InternedString,
|
pub feature: InternedString,
|
||||||
pub since: Option<InternedString>,
|
pub depr: Option<Deprecation>,
|
||||||
pub deprecated_since: Option<InternedString>,
|
|
||||||
// The reason for the current stability level. If deprecated, the
|
|
||||||
// reason for deprecation.
|
|
||||||
pub reason: Option<InternedString>,
|
|
||||||
// The relevant rust-lang issue
|
|
||||||
pub issue: Option<u32>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The available stability levels.
|
/// The available stability levels.
|
||||||
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Copy, Eq, Hash)]
|
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
|
||||||
pub enum StabilityLevel {
|
pub enum StabilityLevel {
|
||||||
Unstable,
|
// Reason for the current stability level and the relevant rust-lang issue
|
||||||
Stable,
|
Unstable { reason: Option<InternedString>, issue: u32 },
|
||||||
|
Stable { since: InternedString },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for StabilityLevel {
|
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
pub struct Deprecation {
|
||||||
fmt::Debug::fmt(self, f)
|
pub since: InternedString,
|
||||||
}
|
pub reason: InternedString,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_stability_generic<'a,
|
impl StabilityLevel {
|
||||||
AM: AttrMetaMethods,
|
pub fn is_unstable(&self) -> bool { if let Unstable {..} = *self { true } else { false }}
|
||||||
I: Iterator<Item=&'a AM>>
|
pub fn is_stable(&self) -> bool { if let Stable {..} = *self { true } else { false }}
|
||||||
(diagnostic: &SpanHandler, attrs: I, item_sp: Span)
|
}
|
||||||
-> (Option<Stability>, Vec<&'a AM>) {
|
|
||||||
|
|
||||||
|
fn find_stability_generic<'a, I>(diagnostic: &SpanHandler,
|
||||||
|
attrs_iter: I,
|
||||||
|
item_sp: Span)
|
||||||
|
-> Option<Stability>
|
||||||
|
where I: Iterator<Item = &'a Attribute>
|
||||||
|
{
|
||||||
let mut stab: Option<Stability> = None;
|
let mut stab: Option<Stability> = None;
|
||||||
let mut deprecated: Option<(Option<InternedString>, Option<InternedString>)> = None;
|
let mut depr: Option<Deprecation> = None;
|
||||||
let mut used_attrs: Vec<&'a AM> = vec![];
|
|
||||||
|
|
||||||
'outer: for attr in attrs {
|
'outer: for attr in attrs_iter {
|
||||||
let tag = attr.name();
|
let tag = attr.name();
|
||||||
let tag = &tag[..];
|
let tag = &*tag;
|
||||||
if tag != "deprecated" && tag != "unstable" && tag != "stable" {
|
if tag != "deprecated" && tag != "unstable" && tag != "stable" {
|
||||||
continue // not a stability level
|
continue // not a stability level
|
||||||
}
|
}
|
||||||
|
|
||||||
used_attrs.push(attr);
|
mark_used(attr);
|
||||||
|
|
||||||
let (feature, since, reason, issue) = match attr.meta_item_list() {
|
if let Some(metas) = attr.meta_item_list() {
|
||||||
Some(metas) => {
|
let get = |meta: &MetaItem, item: &mut Option<InternedString>| {
|
||||||
let mut feature = None;
|
if item.is_some() {
|
||||||
let mut since = None;
|
diagnostic.span_err(meta.span, &format!("multiple '{}' items",
|
||||||
let mut reason = None;
|
meta.name()));
|
||||||
let mut issue = None;
|
return false
|
||||||
for meta in metas {
|
}
|
||||||
match &*meta.name() {
|
if let Some(v) = meta.value_str() {
|
||||||
"feature" => {
|
*item = Some(v);
|
||||||
match meta.value_str() {
|
true
|
||||||
Some(v) => feature = Some(v),
|
} else {
|
||||||
None => {
|
diagnostic.span_err(meta.span, "incorrect meta item");
|
||||||
diagnostic.span_err(meta.span, "incorrect meta item");
|
false
|
||||||
continue 'outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"since" => {
|
|
||||||
match meta.value_str() {
|
|
||||||
Some(v) => since = Some(v),
|
|
||||||
None => {
|
|
||||||
diagnostic.span_err(meta.span, "incorrect meta item");
|
|
||||||
continue 'outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"reason" => {
|
|
||||||
match meta.value_str() {
|
|
||||||
Some(v) => reason = Some(v),
|
|
||||||
None => {
|
|
||||||
diagnostic.span_err(meta.span, "incorrect meta item");
|
|
||||||
continue 'outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"issue" => {
|
|
||||||
match meta.value_str().and_then(|s| s.parse().ok()) {
|
|
||||||
Some(v) => issue = Some(v),
|
|
||||||
None => {
|
|
||||||
diagnostic.span_err(meta.span, "incorrect meta item");
|
|
||||||
continue 'outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
(feature, since, reason, issue)
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
diagnostic.span_err(attr.span(), "incorrect stability attribute type");
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Deprecated tags don't require feature names
|
|
||||||
if feature == None && tag != "deprecated" {
|
|
||||||
diagnostic.span_err(attr.span(), "missing 'feature'");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unstable tags don't require a version
|
|
||||||
if since == None && tag != "unstable" {
|
|
||||||
diagnostic.span_err(attr.span(), "missing 'since'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if tag == "unstable" || tag == "stable" {
|
|
||||||
if stab.is_some() {
|
|
||||||
diagnostic.span_err(item_sp, "multiple stability levels");
|
|
||||||
}
|
|
||||||
|
|
||||||
let level = match tag {
|
|
||||||
"unstable" => Unstable,
|
|
||||||
"stable" => Stable,
|
|
||||||
_ => unreachable!()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
stab = Some(Stability {
|
match tag {
|
||||||
level: level,
|
"deprecated" => {
|
||||||
feature: feature.unwrap_or(intern_and_get_ident("bogus")),
|
if depr.is_some() {
|
||||||
since: since,
|
diagnostic.span_err(item_sp, "multiple deprecated attributes");
|
||||||
deprecated_since: None,
|
break
|
||||||
reason: reason,
|
}
|
||||||
issue: issue,
|
|
||||||
});
|
|
||||||
} else { // "deprecated"
|
|
||||||
if deprecated.is_some() {
|
|
||||||
diagnostic.span_err(item_sp, "multiple deprecated attributes");
|
|
||||||
}
|
|
||||||
|
|
||||||
deprecated = Some((since, reason));
|
let mut since = None;
|
||||||
|
let mut reason = None;
|
||||||
|
for meta in metas {
|
||||||
|
match &*meta.name() {
|
||||||
|
"since" => if !get(meta, &mut since) { continue 'outer },
|
||||||
|
"reason" => if !get(meta, &mut reason) { continue 'outer },
|
||||||
|
_ => {
|
||||||
|
diagnostic.span_err(meta.span, &format!("unknown meta item '{}'",
|
||||||
|
meta.name()));
|
||||||
|
continue 'outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match (since, reason) {
|
||||||
|
(Some(since), Some(reason)) => {
|
||||||
|
depr = Some(Deprecation {
|
||||||
|
since: since,
|
||||||
|
reason: reason,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
(None, _) => {
|
||||||
|
diagnostic.span_err(attr.span(), "missing 'since'");
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
diagnostic.span_err(attr.span(), "missing 'reason'");
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"unstable" => {
|
||||||
|
if stab.is_some() {
|
||||||
|
diagnostic.span_err(item_sp, "multiple stability levels");
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut feature = None;
|
||||||
|
let mut reason = None;
|
||||||
|
let mut issue = None;
|
||||||
|
for meta in metas {
|
||||||
|
match &*meta.name() {
|
||||||
|
"feature" => if !get(meta, &mut feature) { continue 'outer },
|
||||||
|
"reason" => if !get(meta, &mut reason) { continue 'outer },
|
||||||
|
"issue" => if !get(meta, &mut issue) { continue 'outer },
|
||||||
|
_ => {
|
||||||
|
diagnostic.span_err(meta.span, &format!("unknown meta item '{}'",
|
||||||
|
meta.name()));
|
||||||
|
continue 'outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match (feature, reason, issue) {
|
||||||
|
(Some(feature), reason, Some(issue)) => {
|
||||||
|
stab = Some(Stability {
|
||||||
|
level: Unstable {
|
||||||
|
reason: reason,
|
||||||
|
issue: {
|
||||||
|
if let Ok(issue) = issue.parse() {
|
||||||
|
issue
|
||||||
|
} else {
|
||||||
|
diagnostic.span_err(attr.span(), "incorrect 'issue'");
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
feature: feature,
|
||||||
|
depr: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
(None, _, _) => {
|
||||||
|
diagnostic.span_err(attr.span(), "missing 'feature'");
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
diagnostic.span_err(attr.span(), "missing 'issue'");
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"stable" => {
|
||||||
|
if stab.is_some() {
|
||||||
|
diagnostic.span_err(item_sp, "multiple stability levels");
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut feature = None;
|
||||||
|
let mut since = None;
|
||||||
|
for meta in metas {
|
||||||
|
match &*meta.name() {
|
||||||
|
"feature" => if !get(meta, &mut feature) { continue 'outer },
|
||||||
|
"since" => if !get(meta, &mut since) { continue 'outer },
|
||||||
|
_ => {
|
||||||
|
diagnostic.span_err(meta.span, &format!("unknown meta item '{}'",
|
||||||
|
meta.name()));
|
||||||
|
continue 'outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match (feature, since) {
|
||||||
|
(Some(feature), Some(since)) => {
|
||||||
|
stab = Some(Stability {
|
||||||
|
level: Stable {
|
||||||
|
since: since,
|
||||||
|
},
|
||||||
|
feature: feature,
|
||||||
|
depr: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
(None, _) => {
|
||||||
|
diagnostic.span_err(attr.span(), "missing 'feature'");
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
diagnostic.span_err(attr.span(), "missing 'since'");
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
diagnostic.span_err(attr.span(), "incorrect stability attribute type");
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge the deprecation info into the stability info
|
// Merge the deprecation info into the stability info
|
||||||
if deprecated.is_some() {
|
if let Some(depr) = depr {
|
||||||
match stab {
|
if let Some(ref mut stab) = stab {
|
||||||
Some(ref mut s) => {
|
if let Unstable {reason: ref mut reason @ None, ..} = stab.level {
|
||||||
let (since, reason) = deprecated.unwrap();
|
*reason = Some(depr.reason.clone())
|
||||||
s.deprecated_since = since;
|
|
||||||
s.reason = reason;
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
diagnostic.span_err(item_sp, "deprecated attribute must be paired with \
|
|
||||||
either stable or unstable attribute");
|
|
||||||
}
|
}
|
||||||
|
stab.depr = Some(depr);
|
||||||
|
} else {
|
||||||
|
diagnostic.span_err(item_sp, "deprecated attribute must be paired with \
|
||||||
|
either stable or unstable attribute");
|
||||||
}
|
}
|
||||||
} else if stab.as_ref().map_or(false, |s| s.level == Unstable && s.issue.is_none()) {
|
|
||||||
// non-deprecated unstable items need to point to issues.
|
|
||||||
diagnostic.span_err(item_sp,
|
|
||||||
"non-deprecated unstable items need to point \
|
|
||||||
to an issue with `issue = \"NNN\"`");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(stab, used_attrs)
|
stab
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the first stability attribute. `None` if none exists.
|
/// Find the first stability attribute. `None` if none exists.
|
||||||
pub fn find_stability(diagnostic: &SpanHandler, attrs: &[Attribute],
|
pub fn find_stability(diagnostic: &SpanHandler, attrs: &[Attribute],
|
||||||
item_sp: Span) -> Option<Stability> {
|
item_sp: Span) -> Option<Stability> {
|
||||||
let (s, used) = find_stability_generic(diagnostic, attrs.iter(), item_sp);
|
find_stability_generic(diagnostic, attrs.iter(), item_sp)
|
||||||
for used in used { mark_used(used) }
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P<MetaItem>]) {
|
pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P<MetaItem>]) {
|
||||||
|
@ -593,7 +593,7 @@ impl<'a> ExtCtxt<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "rustc_private")]
|
#[unstable(feature = "rustc_private", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0",
|
#[deprecated(since = "1.0.0",
|
||||||
reason = "Replaced with `expander().fold_expr()`")]
|
reason = "Replaced with `expander().fold_expr()`")]
|
||||||
pub fn expand_expr(&mut self, e: P<ast::Expr>) -> P<ast::Expr> {
|
pub fn expand_expr(&mut self, e: P<ast::Expr>) -> P<ast::Expr> {
|
||||||
|
@ -129,7 +129,7 @@ impl<T> SmallVector<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Deprecated: use `into_iter`.
|
/// Deprecated: use `into_iter`.
|
||||||
#[unstable(feature = "rustc_private")]
|
#[unstable(feature = "rustc_private", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0", reason = "use into_iter")]
|
#[deprecated(since = "1.0.0", reason = "use into_iter")]
|
||||||
pub fn move_iter(self) -> IntoIter<T> {
|
pub fn move_iter(self) -> IntoIter<T> {
|
||||||
self.into_iter()
|
self.into_iter()
|
||||||
|
@ -29,7 +29,7 @@ pub mod stable_mod {
|
|||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
pub mod unstable_mod {
|
pub mod unstable_mod {
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub fn deprecated() {}
|
pub fn deprecated() {}
|
||||||
|
|
||||||
pub fn unstable() {}
|
pub fn unstable() {}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#![unstable(feature = "test_feature", issue = "0")]
|
#![unstable(feature = "test_feature", issue = "0")]
|
||||||
|
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub fn foo() -> usize {
|
pub fn foo() -> usize {
|
||||||
20
|
20
|
||||||
}
|
}
|
||||||
|
@ -14,14 +14,14 @@
|
|||||||
#![stable(feature = "lint_stability", since = "1.0.0")]
|
#![stable(feature = "lint_stability", since = "1.0.0")]
|
||||||
|
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub fn deprecated() {}
|
pub fn deprecated() {}
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
#[deprecated(since = "1.0.0", reason = "text")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub fn deprecated_text() {}
|
pub fn deprecated_text() {}
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub fn deprecated_unstable() {}
|
pub fn deprecated_unstable() {}
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0", reason = "text")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
@ -34,7 +34,7 @@ pub fn unstable_text() {}
|
|||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn stable() {}
|
pub fn stable() {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0", reason = "text")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn stable_text() {}
|
pub fn stable_text() {}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@ -42,14 +42,14 @@ pub struct MethodTester;
|
|||||||
|
|
||||||
impl MethodTester {
|
impl MethodTester {
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub fn method_deprecated(&self) {}
|
pub fn method_deprecated(&self) {}
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
#[deprecated(since = "1.0.0", reason = "text")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub fn method_deprecated_text(&self) {}
|
pub fn method_deprecated_text(&self) {}
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub fn method_deprecated_unstable(&self) {}
|
pub fn method_deprecated_unstable(&self) {}
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0", reason = "text")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
@ -62,21 +62,21 @@ impl MethodTester {
|
|||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn method_stable(&self) {}
|
pub fn method_stable(&self) {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0", reason = "text")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn method_stable_text(&self) {}
|
pub fn method_stable_text(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
pub trait Trait {
|
pub trait Trait {
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
fn trait_deprecated(&self) {}
|
fn trait_deprecated(&self) {}
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
#[deprecated(since = "1.0.0", reason = "text")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
fn trait_deprecated_text(&self) {}
|
fn trait_deprecated_text(&self) {}
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
fn trait_deprecated_unstable(&self) {}
|
fn trait_deprecated_unstable(&self) {}
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0", reason = "text")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
@ -89,7 +89,7 @@ pub trait Trait {
|
|||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
fn trait_stable(&self) {}
|
fn trait_stable(&self) {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0", reason = "text")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
fn trait_stable_text(&self) {}
|
fn trait_stable_text(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,12 +99,12 @@ impl Trait for MethodTester {}
|
|||||||
pub trait UnstableTrait { fn dummy(&self) { } }
|
pub trait UnstableTrait { fn dummy(&self) { } }
|
||||||
|
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub struct DeprecatedStruct {
|
pub struct DeprecatedStruct {
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")] pub i: isize
|
#[stable(feature = "test_feature", since = "1.0.0")] pub i: isize
|
||||||
}
|
}
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub struct DeprecatedUnstableStruct {
|
pub struct DeprecatedUnstableStruct {
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")] pub i: isize
|
#[stable(feature = "test_feature", since = "1.0.0")] pub i: isize
|
||||||
}
|
}
|
||||||
@ -118,10 +118,10 @@ pub struct StableStruct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub struct DeprecatedUnitStruct;
|
pub struct DeprecatedUnitStruct;
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub struct DeprecatedUnstableUnitStruct;
|
pub struct DeprecatedUnstableUnitStruct;
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
pub struct UnstableUnitStruct;
|
pub struct UnstableUnitStruct;
|
||||||
@ -131,10 +131,10 @@ pub struct StableUnitStruct;
|
|||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
pub enum Enum {
|
pub enum Enum {
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
DeprecatedVariant,
|
DeprecatedVariant,
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
DeprecatedUnstableVariant,
|
DeprecatedUnstableVariant,
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
UnstableVariant,
|
UnstableVariant,
|
||||||
@ -144,10 +144,10 @@ pub enum Enum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub struct DeprecatedTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
|
pub struct DeprecatedTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub struct DeprecatedUnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
|
pub struct DeprecatedUnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
pub struct UnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
|
pub struct UnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
|
||||||
|
@ -18,7 +18,7 @@ pub struct Stable {
|
|||||||
pub inherit: u8, // it's a lie (stable doesn't inherit)
|
pub inherit: u8, // it's a lie (stable doesn't inherit)
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
pub override1: u8,
|
pub override1: u8,
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
pub override2: u8,
|
pub override2: u8,
|
||||||
}
|
}
|
||||||
@ -27,14 +27,14 @@ pub struct Stable {
|
|||||||
pub struct Stable2(#[stable(feature = "rust1", since = "1.0.0")] pub u8,
|
pub struct Stable2(#[stable(feature = "rust1", since = "1.0.0")] pub u8,
|
||||||
#[unstable(feature = "test_feature", issue = "0")] pub u8,
|
#[unstable(feature = "test_feature", issue = "0")] pub u8,
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")] pub u8);
|
#[deprecated(since = "1.0.0", reason = "text")] pub u8);
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
pub struct Unstable {
|
pub struct Unstable {
|
||||||
pub inherit: u8,
|
pub inherit: u8,
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub override1: u8,
|
pub override1: u8,
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
pub override2: u8,
|
pub override2: u8,
|
||||||
}
|
}
|
||||||
@ -43,10 +43,10 @@ pub struct Unstable {
|
|||||||
pub struct Unstable2(pub u8,
|
pub struct Unstable2(pub u8,
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] pub u8,
|
#[stable(feature = "rust1", since = "1.0.0")] pub u8,
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")] pub u8);
|
#[deprecated(since = "1.0.0", reason = "text")] pub u8);
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(feature = "rust1", since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub struct Deprecated {
|
pub struct Deprecated {
|
||||||
pub inherit: u8,
|
pub inherit: u8,
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@ -56,7 +56,7 @@ pub struct Deprecated {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(feature = "rust1", since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub struct Deprecated2(pub u8,
|
pub struct Deprecated2(pub u8,
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] pub u8,
|
#[stable(feature = "rust1", since = "1.0.0")] pub u8,
|
||||||
#[unstable(feature = "test_feature", issue = "0")] pub u8);
|
#[unstable(feature = "test_feature", issue = "0")] pub u8);
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
struct Foo;
|
struct Foo;
|
||||||
|
|
||||||
impl Foo {
|
impl Foo {
|
||||||
#[unstable(feature = "test_feature")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
fn foo(self) {}
|
fn foo(self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
extern crate lint_output_format; //~ ERROR use of unstable library feature
|
extern crate lint_output_format; //~ ERROR use of unstable library feature
|
||||||
use lint_output_format::{foo, bar}; //~ ERROR use of unstable library feature
|
use lint_output_format::{foo, bar}; //~ ERROR use of unstable library feature
|
||||||
//~^ WARNING use of deprecated item,
|
//~^ WARNING use of deprecated item: text,
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _x = foo(); //~ WARNING #[warn(deprecated)] on by default
|
let _x = foo(); //~ WARNING #[warn(deprecated)] on by default
|
||||||
|
@ -189,7 +189,7 @@ mod this_crate {
|
|||||||
inherit: u8,
|
inherit: u8,
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
override1: u8,
|
override1: u8,
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
override2: u8,
|
override2: u8,
|
||||||
}
|
}
|
||||||
@ -198,14 +198,14 @@ mod this_crate {
|
|||||||
struct Stable2(u8,
|
struct Stable2(u8,
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] u8,
|
#[stable(feature = "rust1", since = "1.0.0")] u8,
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")] u8);
|
#[deprecated(since = "1.0.0", reason = "text")] u8);
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
struct Unstable {
|
struct Unstable {
|
||||||
inherit: u8,
|
inherit: u8,
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
override1: u8,
|
override1: u8,
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
override2: u8,
|
override2: u8,
|
||||||
}
|
}
|
||||||
@ -214,10 +214,10 @@ mod this_crate {
|
|||||||
struct Unstable2(u8,
|
struct Unstable2(u8,
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] u8,
|
#[stable(feature = "rust1", since = "1.0.0")] u8,
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")] u8);
|
#[deprecated(since = "1.0.0", reason = "text")] u8);
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(feature = "rust1", since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
struct Deprecated {
|
struct Deprecated {
|
||||||
inherit: u8,
|
inherit: u8,
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@ -227,7 +227,7 @@ mod this_crate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(feature = "rust1", since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
struct Deprecated2(u8,
|
struct Deprecated2(u8,
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] u8,
|
#[stable(feature = "rust1", since = "1.0.0")] u8,
|
||||||
#[unstable(feature = "test_feature", issue = "0")] u8);
|
#[unstable(feature = "test_feature", issue = "0")] u8);
|
||||||
|
@ -258,7 +258,7 @@ mod inheritance {
|
|||||||
|
|
||||||
mod this_crate {
|
mod this_crate {
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub fn deprecated() {}
|
pub fn deprecated() {}
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0", reason = "text")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
@ -271,7 +271,7 @@ mod this_crate {
|
|||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn stable() {}
|
pub fn stable() {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0", reason = "text")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn stable_text() {}
|
pub fn stable_text() {}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@ -279,7 +279,7 @@ mod this_crate {
|
|||||||
|
|
||||||
impl MethodTester {
|
impl MethodTester {
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub fn method_deprecated(&self) {}
|
pub fn method_deprecated(&self) {}
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0", reason = "text")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
@ -292,13 +292,13 @@ mod this_crate {
|
|||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn method_stable(&self) {}
|
pub fn method_stable(&self) {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0", reason = "text")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn method_stable_text(&self) {}
|
pub fn method_stable_text(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Trait {
|
pub trait Trait {
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
fn trait_deprecated(&self) {}
|
fn trait_deprecated(&self) {}
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0", reason = "text")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
@ -311,14 +311,14 @@ mod this_crate {
|
|||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
fn trait_stable(&self) {}
|
fn trait_stable(&self) {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0", reason = "text")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
fn trait_stable_text(&self) {}
|
fn trait_stable_text(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Trait for MethodTester {}
|
impl Trait for MethodTester {}
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub struct DeprecatedStruct {
|
pub struct DeprecatedStruct {
|
||||||
#[stable(feature = "test_feature", since = "1.0.0")] i: isize
|
#[stable(feature = "test_feature", since = "1.0.0")] i: isize
|
||||||
}
|
}
|
||||||
@ -332,7 +332,7 @@ mod this_crate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub struct DeprecatedUnitStruct;
|
pub struct DeprecatedUnitStruct;
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
pub struct UnstableUnitStruct;
|
pub struct UnstableUnitStruct;
|
||||||
@ -341,7 +341,7 @@ mod this_crate {
|
|||||||
|
|
||||||
pub enum Enum {
|
pub enum Enum {
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
DeprecatedVariant,
|
DeprecatedVariant,
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
UnstableVariant,
|
UnstableVariant,
|
||||||
@ -351,7 +351,7 @@ mod this_crate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub struct DeprecatedTupleStruct(isize);
|
pub struct DeprecatedTupleStruct(isize);
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
pub struct UnstableTupleStruct(isize);
|
pub struct UnstableTupleStruct(isize);
|
||||||
@ -472,7 +472,7 @@ mod this_crate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
fn test_fn_body() {
|
fn test_fn_body() {
|
||||||
fn fn_in_body() {}
|
fn fn_in_body() {}
|
||||||
fn_in_body();
|
fn_in_body();
|
||||||
@ -480,7 +480,7 @@ mod this_crate {
|
|||||||
|
|
||||||
impl MethodTester {
|
impl MethodTester {
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
fn test_method_body(&self) {
|
fn test_method_body(&self) {
|
||||||
fn fn_in_body() {}
|
fn fn_in_body() {}
|
||||||
fn_in_body();
|
fn_in_body();
|
||||||
@ -488,7 +488,7 @@ mod this_crate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "test_feature", issue = "0")]
|
#[unstable(feature = "test_feature", issue = "0")]
|
||||||
#[deprecated(since = "1.0.0")]
|
#[deprecated(since = "1.0.0", reason = "text")]
|
||||||
pub trait DeprecatedTrait {
|
pub trait DeprecatedTrait {
|
||||||
fn dummy(&self) { }
|
fn dummy(&self) { }
|
||||||
}
|
}
|
||||||
|
@ -14,22 +14,19 @@
|
|||||||
#![staged_api]
|
#![staged_api]
|
||||||
|
|
||||||
mod bogus_attribute_types_1 {
|
mod bogus_attribute_types_1 {
|
||||||
#[stable(feature = "a", since = "a", reason)] //~ ERROR incorrect meta item
|
#[stable(feature = "a", since = "a", reason)] //~ ERROR unknown meta item 'reason'
|
||||||
fn f1() { }
|
fn f1() { }
|
||||||
|
|
||||||
#[stable(feature = "a", since, reason = "a")] //~ ERROR incorrect meta item
|
#[stable(feature = "a", since)] //~ ERROR incorrect meta item
|
||||||
fn f2() { }
|
fn f2() { }
|
||||||
|
|
||||||
#[stable(feature, since = "a", reason = "a")] //~ ERROR incorrect meta item
|
#[stable(feature, since = "a")] //~ ERROR incorrect meta item
|
||||||
fn f3() { }
|
fn f3() { }
|
||||||
|
|
||||||
#[stable(feature = "a", since = "a", reason(b))] //~ ERROR incorrect meta item
|
#[stable(feature = "a", since(b))] //~ ERROR incorrect meta item
|
||||||
fn f4() { }
|
|
||||||
|
|
||||||
#[stable(feature = "a", since(b), reason = "a")] //~ ERROR incorrect meta item
|
|
||||||
fn f5() { }
|
fn f5() { }
|
||||||
|
|
||||||
#[stable(feature(b), since = "a", reason = "a")] //~ ERROR incorrect meta item
|
#[stable(feature(b), since = "a")] //~ ERROR incorrect meta item
|
||||||
fn f6() { }
|
fn f6() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,11 +53,11 @@ mod bogus_attribute_types_2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod missing_feature_names {
|
mod missing_feature_names {
|
||||||
#[unstable(since = "a", issue = "0")] //~ ERROR missing 'feature'
|
#[unstable(issue = "0")] //~ ERROR missing 'feature'
|
||||||
fn f1() { }
|
fn f1() { }
|
||||||
|
|
||||||
#[unstable(feature = "a")]
|
#[unstable(feature = "a")] //~ ERROR missing 'issue'
|
||||||
fn f2() { } //~ ERROR need to point to an issue
|
fn f2() { }
|
||||||
|
|
||||||
#[stable(since = "a")] //~ ERROR missing 'feature'
|
#[stable(since = "a")] //~ ERROR missing 'feature'
|
||||||
fn f3() { }
|
fn f3() { }
|
||||||
@ -75,12 +72,12 @@ mod missing_version {
|
|||||||
fn f2() { }
|
fn f2() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "a", since = "b", issue = "0")]
|
#[unstable(feature = "a", issue = "0")]
|
||||||
#[stable(feature = "a", since = "b")]
|
#[stable(feature = "a", since = "b")]
|
||||||
fn multiple1() { } //~ ERROR multiple stability levels
|
fn multiple1() { } //~ ERROR multiple stability levels
|
||||||
|
|
||||||
#[unstable(feature = "a", since = "b", issue = "0")]
|
#[unstable(feature = "a", issue = "0")]
|
||||||
#[unstable(feature = "a", since = "b", issue = "0")]
|
#[unstable(feature = "a", issue = "0")]
|
||||||
fn multiple2() { } //~ ERROR multiple stability levels
|
fn multiple2() { } //~ ERROR multiple stability levels
|
||||||
|
|
||||||
#[stable(feature = "a", since = "b")]
|
#[stable(feature = "a", since = "b")]
|
||||||
@ -88,12 +85,12 @@ fn multiple2() { } //~ ERROR multiple stability levels
|
|||||||
fn multiple3() { } //~ ERROR multiple stability levels
|
fn multiple3() { } //~ ERROR multiple stability levels
|
||||||
|
|
||||||
#[stable(feature = "a", since = "b")]
|
#[stable(feature = "a", since = "b")]
|
||||||
#[deprecated(since = "b")]
|
#[deprecated(since = "b", reason = "text")]
|
||||||
#[deprecated(since = "b")]
|
#[deprecated(since = "b", reason = "text")]
|
||||||
fn multiple4() { } //~ ERROR multiple deprecated attributes
|
fn multiple4() { } //~ ERROR multiple deprecated attributes
|
||||||
//~^ ERROR Invalid stability or deprecation version found
|
//~^ ERROR Invalid stability or deprecation version found
|
||||||
|
|
||||||
#[deprecated(since = "a")]
|
#[deprecated(since = "a", reason = "text")]
|
||||||
fn deprecated_without_unstable_or_stable() { } //~ ERROR deprecated attribute must be paired
|
fn deprecated_without_unstable_or_stable() { } //~ ERROR deprecated attribute must be paired
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
Loading…
Reference in New Issue
Block a user