Implement support for indicating the stability of items.
There are 6 new compiler recognised attributes: deprecated, experimental,
unstable, stable, frozen, locked (these levels are taken directly from
Node's "stability index"[1]). These indicate the stability of the
item to which they are attached; e.g. `#[deprecated] fn foo() { .. }`
says that `foo` is deprecated.
This comes with 3 lints for the first 3 levels (with matching names) that
will detect the use of items marked with them (the `unstable` lint
includes items with no stability attribute). The attributes can be given
a short text note that will be displayed by the lint. An example:
#[warn(unstable)]; // `allow` by default
#[deprecated="use `bar`"]
fn foo() { }
#[stable]
fn bar() { }
fn baz() { }
fn main() {
foo(); // "warning: use of deprecated item: use `bar`"
bar(); // all fine
baz(); // "warning: use of unmarked item"
}
The lints currently only check the "edges" of the AST: i.e. functions,
methods[2], structs and enum variants. Any stability attributes on modules,
enums, traits and impls are not checked.
[1]: http://nodejs.org/api/documentation.html
[2]: the method check is currently incorrect and doesn't work.
This commit is contained in:
parent
7048e05d5f
commit
506f69aed7
8 changed files with 745 additions and 3 deletions
|
|
@ -330,6 +330,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
|
|||
encode_name(ecx, ebml_w, variant.node.name);
|
||||
encode_parent_item(ebml_w, local_def(id));
|
||||
encode_visibility(ebml_w, variant.node.vis);
|
||||
encode_attributes(ebml_w, variant.node.attrs);
|
||||
match variant.node.kind {
|
||||
ast::tuple_variant_kind(ref args)
|
||||
if args.len() > 0 && generics.ty_params.len() == 0 => {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
use driver::session;
|
||||
use middle::ty;
|
||||
use middle::pat_util;
|
||||
use metadata::csearch;
|
||||
use util::ppaux::{ty_to_str};
|
||||
|
||||
use std::cmp;
|
||||
|
|
@ -27,7 +28,7 @@ use std::u8;
|
|||
use extra::smallintmap::SmallIntMap;
|
||||
use syntax::ast_map;
|
||||
use syntax::attr;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::attr::{AttrMetaMethods, AttributeMethods};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::codemap;
|
||||
use syntax::parse::token;
|
||||
|
|
@ -97,6 +98,10 @@ pub enum lint {
|
|||
missing_doc,
|
||||
unreachable_code,
|
||||
|
||||
deprecated,
|
||||
experimental,
|
||||
unstable,
|
||||
|
||||
warnings,
|
||||
}
|
||||
|
||||
|
|
@ -281,6 +286,27 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
|
|||
default: warn
|
||||
}),
|
||||
|
||||
("deprecated",
|
||||
LintSpec {
|
||||
lint: deprecated,
|
||||
desc: "detects use of #[deprecated] items",
|
||||
default: warn
|
||||
}),
|
||||
|
||||
("experimental",
|
||||
LintSpec {
|
||||
lint: experimental,
|
||||
desc: "detects use of #[experimental] items",
|
||||
default: warn
|
||||
}),
|
||||
|
||||
("unstable",
|
||||
LintSpec {
|
||||
lint: unstable,
|
||||
desc: "detects use of #[unstable] items (incl. items with no stability attribute)",
|
||||
default: allow
|
||||
}),
|
||||
|
||||
("warnings",
|
||||
LintSpec {
|
||||
lint: warnings,
|
||||
|
|
@ -1375,6 +1401,107 @@ fn lint_missing_doc() -> @mut OuterLint {
|
|||
@mut MissingDocLintVisitor { stopping_on_items: false } as @mut OuterLint
|
||||
}
|
||||
|
||||
/// Checks for use of items with #[deprecated], #[experimental] and
|
||||
/// #[unstable] (or none of them) attributes.
|
||||
struct StabilityLintVisitor { stopping_on_items: bool }
|
||||
|
||||
impl StabilityLintVisitor {
|
||||
fn handle_def(&mut self, sp: Span, def: &ast::Def, cx: @mut Context) {
|
||||
let id = ast_util::def_id_of_def(*def);
|
||||
|
||||
let stability = if ast_util::is_local(id) {
|
||||
// this crate
|
||||
match cx.tcx.items.find(&id.node) {
|
||||
Some(ast_node) => {
|
||||
let s = do ast_node.with_attrs |attrs| {
|
||||
do attrs.map_move |a| {
|
||||
attr::find_stability(a.iter().map(|a| a.meta()))
|
||||
}
|
||||
};
|
||||
match s {
|
||||
Some(s) => s,
|
||||
|
||||
// no possibility of having attributes
|
||||
// (e.g. it's a local variable), so just
|
||||
// ignore it.
|
||||
None => return
|
||||
}
|
||||
}
|
||||
_ => cx.tcx.sess.bug(fmt!("handle_def: %? not found", id))
|
||||
}
|
||||
} else {
|
||||
// cross-crate
|
||||
|
||||
let mut s = None;
|
||||
// run through all the attributes and take the first
|
||||
// stability one.
|
||||
do csearch::get_item_attrs(cx.tcx.cstore, id) |meta_items| {
|
||||
if s.is_none() {
|
||||
s = attr::find_stability(meta_items.move_iter())
|
||||
}
|
||||
}
|
||||
s
|
||||
};
|
||||
|
||||
let (lint, label) = match stability {
|
||||
// no stability attributes == Unstable
|
||||
None => (unstable, "unmarked"),
|
||||
Some(attr::Stability { level: attr::Unstable, _ }) => (unstable, "unstable"),
|
||||
Some(attr::Stability { level: attr::Experimental, _ }) => {
|
||||
(experimental, "experimental")
|
||||
}
|
||||
Some(attr::Stability { level: attr::Deprecated, _ }) => (deprecated, "deprecated"),
|
||||
_ => return
|
||||
};
|
||||
|
||||
let msg = match stability {
|
||||
Some(attr::Stability { text: Some(ref s), _ }) => {
|
||||
fmt!("use of %s item: %s", label, *s)
|
||||
}
|
||||
_ => fmt!("use of %s item", label)
|
||||
};
|
||||
|
||||
cx.span_lint(lint, sp, msg);
|
||||
}
|
||||
}
|
||||
|
||||
impl SubitemStoppableVisitor for StabilityLintVisitor {
|
||||
fn is_running_on_items(&mut self) -> bool { !self.stopping_on_items }
|
||||
}
|
||||
|
||||
impl Visitor<@mut Context> for StabilityLintVisitor {
|
||||
fn visit_item(&mut self, i:@ast::item, e:@mut Context) {
|
||||
self.OVERRIDE_visit_item(i, e);
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&ast::fn_decl,
|
||||
b:&ast::Block, s:Span, n:ast::NodeId, e:@mut Context) {
|
||||
self.OVERRIDE_visit_fn(fk, fd, b, s, n, e);
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, ex: @ast::Expr, cx: @mut Context) {
|
||||
match ex.node {
|
||||
ast::ExprMethodCall(*) |
|
||||
ast::ExprPath(*) |
|
||||
ast::ExprStruct(*) => {
|
||||
match cx.tcx.def_map.find(&ex.id) {
|
||||
Some(def) => self.handle_def(ex.span, def, cx),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
visit::walk_expr(self, ex, cx)
|
||||
}
|
||||
}
|
||||
|
||||
outer_lint_boilerplate_impl!(StabilityLintVisitor)
|
||||
|
||||
fn lint_stability() -> @mut OuterLint {
|
||||
@mut StabilityLintVisitor { stopping_on_items: false } as @mut OuterLint
|
||||
}
|
||||
|
||||
struct LintCheckVisitor;
|
||||
|
||||
impl Visitor<@mut Context> for LintCheckVisitor {
|
||||
|
|
@ -1458,6 +1585,7 @@ pub fn check_crate(tcx: ty::ctxt, crate: @ast::Crate) {
|
|||
cx.add_old_lint(lint_unused_mut());
|
||||
cx.add_old_lint(lint_unnecessary_allocations());
|
||||
cx.add_old_lint(lint_missing_doc());
|
||||
cx.add_old_lint(lint_stability());
|
||||
cx.add_lint(lint_session(cx));
|
||||
|
||||
// Actually perform the lint checks (iterating the ast)
|
||||
|
|
|
|||
|
|
@ -4706,4 +4706,3 @@ pub fn trait_of_method(tcx: ctxt, def_id: ast::DefId)
|
|||
|
||||
result
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,26 @@ pub enum ast_node {
|
|||
node_callee_scope(@Expr)
|
||||
}
|
||||
|
||||
impl ast_node {
|
||||
pub fn with_attrs<T>(&self, f: &fn(Option<&[Attribute]>) -> T) -> T {
|
||||
let attrs = match *self {
|
||||
node_item(i, _) => Some(i.attrs.as_slice()),
|
||||
node_foreign_item(fi, _, _, _) => Some(fi.attrs.as_slice()),
|
||||
node_trait_method(tm, _, _) => match *tm {
|
||||
required(ref type_m) => Some(type_m.attrs.as_slice()),
|
||||
provided(m) => Some(m.attrs.as_slice())
|
||||
},
|
||||
node_method(m, _, _) => Some(m.attrs.as_slice()),
|
||||
node_variant(ref v, _, _) => Some(v.node.attrs.as_slice()),
|
||||
// unit/tuple structs take the attributes straight from
|
||||
// the struct definition.
|
||||
node_struct_ctor(_, strct, _) => Some(strct.attrs.as_slice()),
|
||||
_ => None
|
||||
};
|
||||
f(attrs)
|
||||
}
|
||||
}
|
||||
|
||||
pub type map = @mut HashMap<NodeId, ast_node>;
|
||||
|
||||
pub struct Ctx {
|
||||
|
|
|
|||
|
|
@ -313,6 +313,44 @@ pub fn test_cfg<AM: AttrMetaMethods, It: Iterator<AM>>
|
|||
no_cfgs || some_cfg_matches
|
||||
}
|
||||
|
||||
/// Represents the #[deprecated="foo"] (etc) attributes.
|
||||
pub struct Stability {
|
||||
level: StabilityLevel,
|
||||
text: Option<@str>
|
||||
}
|
||||
|
||||
/// The available stability levels.
|
||||
#[deriving(Eq,Ord,Clone)]
|
||||
pub enum StabilityLevel {
|
||||
Deprecated,
|
||||
Experimental,
|
||||
Unstable,
|
||||
Stable,
|
||||
Frozen,
|
||||
Locked
|
||||
}
|
||||
|
||||
/// Find the first stability attribute. `None` if none exists.
|
||||
pub fn find_stability<AM: AttrMetaMethods, It: Iterator<AM>>(mut metas: It) -> Option<Stability> {
|
||||
for m in metas {
|
||||
let level = match m.name().as_slice() {
|
||||
"deprecated" => Deprecated,
|
||||
"experimental" => Experimental,
|
||||
"unstable" => Unstable,
|
||||
"stable" => Stable,
|
||||
"frozen" => Frozen,
|
||||
"locked" => Locked,
|
||||
_ => loop // not a stability level
|
||||
};
|
||||
|
||||
return Some(Stability {
|
||||
level: level,
|
||||
text: m.value_str()
|
||||
});
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn require_unique_names(diagnostic: @mut span_handler,
|
||||
metas: &[@MetaItem]) {
|
||||
let mut set = HashSet::new();
|
||||
|
|
|
|||
162
src/test/auxiliary/lint_stability.rs
Normal file
162
src/test/auxiliary/lint_stability.rs
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
// Copyright 2013 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.
|
||||
#[link(name = "lint_stability",
|
||||
vers = "0.1")];
|
||||
#[crate_type = "lib"];
|
||||
|
||||
#[deprecated]
|
||||
pub fn deprecated() {}
|
||||
#[deprecated="text"]
|
||||
pub fn deprecated_text() {}
|
||||
|
||||
#[experimental]
|
||||
pub fn experimental() {}
|
||||
#[experimental="text"]
|
||||
pub fn experimental_text() {}
|
||||
|
||||
#[unstable]
|
||||
pub fn unstable() {}
|
||||
#[unstable="text"]
|
||||
pub fn unstable_text() {}
|
||||
|
||||
pub fn unmarked() {}
|
||||
|
||||
#[stable]
|
||||
pub fn stable() {}
|
||||
#[stable="text"]
|
||||
pub fn stable_text() {}
|
||||
|
||||
#[locked]
|
||||
pub fn locked() {}
|
||||
#[locked="text"]
|
||||
pub fn locked_text() {}
|
||||
|
||||
#[frozen]
|
||||
pub fn frozen() {}
|
||||
#[frozen="text"]
|
||||
pub fn frozen_text() {}
|
||||
|
||||
#[stable]
|
||||
pub struct MethodTester;
|
||||
|
||||
impl MethodTester {
|
||||
#[deprecated]
|
||||
pub fn method_deprecated(&self) {}
|
||||
#[deprecated="text"]
|
||||
pub fn method_deprecated_text(&self) {}
|
||||
|
||||
#[experimental]
|
||||
pub fn method_experimental(&self) {}
|
||||
#[experimental="text"]
|
||||
pub fn method_experimental_text(&self) {}
|
||||
|
||||
#[unstable]
|
||||
pub fn method_unstable(&self) {}
|
||||
#[unstable="text"]
|
||||
pub fn method_unstable_text(&self) {}
|
||||
|
||||
pub fn method_unmarked(&self) {}
|
||||
|
||||
#[stable]
|
||||
pub fn method_stable(&self) {}
|
||||
#[stable="text"]
|
||||
pub fn method_stable_text(&self) {}
|
||||
|
||||
#[locked]
|
||||
pub fn method_locked(&self) {}
|
||||
#[locked="text"]
|
||||
pub fn method_locked_text(&self) {}
|
||||
|
||||
#[frozen]
|
||||
pub fn method_frozen(&self) {}
|
||||
#[frozen="text"]
|
||||
pub fn method_frozen_text(&self) {}
|
||||
}
|
||||
|
||||
pub trait Trait {
|
||||
#[deprecated]
|
||||
fn trait_deprecated(&self) {}
|
||||
#[deprecated="text"]
|
||||
fn trait_deprecated_text(&self) {}
|
||||
|
||||
#[experimental]
|
||||
fn trait_experimental(&self) {}
|
||||
#[experimental="text"]
|
||||
fn trait_experimental_text(&self) {}
|
||||
|
||||
#[unstable]
|
||||
fn trait_unstable(&self) {}
|
||||
#[unstable="text"]
|
||||
fn trait_unstable_text(&self) {}
|
||||
|
||||
fn trait_unmarked(&self) {}
|
||||
|
||||
#[stable]
|
||||
fn trait_stable(&self) {}
|
||||
#[stable="text"]
|
||||
fn trait_stable_text(&self) {}
|
||||
|
||||
#[locked]
|
||||
fn trait_locked(&self) {}
|
||||
#[locked="text"]
|
||||
fn trait_locked_text(&self) {}
|
||||
|
||||
#[frozen]
|
||||
fn trait_frozen(&self) {}
|
||||
#[frozen="text"]
|
||||
fn trait_frozen_text(&self) {}
|
||||
}
|
||||
|
||||
impl Trait for MethodTester {}
|
||||
|
||||
#[deprecated]
|
||||
pub struct DeprecatedStruct { i: int }
|
||||
#[experimental]
|
||||
pub struct ExperimentalStruct { i: int }
|
||||
#[unstable]
|
||||
pub struct UnstableStruct { i: int }
|
||||
pub struct UnmarkedStruct { i: int }
|
||||
#[stable]
|
||||
pub struct StableStruct { i: int }
|
||||
#[frozen]
|
||||
pub struct FrozenStruct { i: int }
|
||||
#[locked]
|
||||
pub struct LockedStruct { i: int }
|
||||
|
||||
#[deprecated]
|
||||
pub struct DeprecatedUnitStruct;
|
||||
#[experimental]
|
||||
pub struct ExperimentalUnitStruct;
|
||||
#[unstable]
|
||||
pub struct UnstableUnitStruct;
|
||||
pub struct UnmarkedUnitStruct;
|
||||
#[stable]
|
||||
pub struct StableUnitStruct;
|
||||
#[frozen]
|
||||
pub struct FrozenUnitStruct;
|
||||
#[locked]
|
||||
pub struct LockedUnitStruct;
|
||||
|
||||
pub enum Enum {
|
||||
#[deprecated]
|
||||
DeprecatedVariant,
|
||||
#[experimental]
|
||||
ExperimentalVariant,
|
||||
#[unstable]
|
||||
UnstableVariant,
|
||||
|
||||
UnmarkedVariant,
|
||||
#[stable]
|
||||
StableVariant,
|
||||
#[frozen]
|
||||
FrozenVariant,
|
||||
#[locked]
|
||||
LockedVariant,
|
||||
}
|
||||
338
src/test/compile-fail/lint-stability.rs
Normal file
338
src/test/compile-fail/lint-stability.rs
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
// xfail-fast aux-build
|
||||
// aux-build:lint_stability.rs
|
||||
|
||||
#[deny(unstable)];
|
||||
#[deny(deprecated)];
|
||||
#[deny(experimental)];
|
||||
|
||||
mod cross_crate {
|
||||
extern mod lint_stability;
|
||||
use self::lint_stability::*;
|
||||
|
||||
fn test() {
|
||||
// XXX: attributes on methods are not encoded cross crate.
|
||||
let foo = MethodTester;
|
||||
|
||||
deprecated(); //~ ERROR use of deprecated item
|
||||
foo.method_deprecated(); // ~ ERROR use of deprecated item
|
||||
foo.trait_deprecated(); // ~ ERROR use of deprecated item
|
||||
|
||||
deprecated_text(); //~ ERROR use of deprecated item: text
|
||||
foo.method_deprecated_text(); // ~ ERROR use of deprecated item: text
|
||||
foo.trait_deprecated_text(); // ~ ERROR use of deprecated item: text
|
||||
|
||||
experimental(); //~ ERROR use of experimental item
|
||||
foo.method_experimental(); // ~ ERROR use of experimental item
|
||||
foo.trait_experimental(); // ~ ERROR use of experimental item
|
||||
|
||||
experimental_text(); //~ ERROR use of experimental item: text
|
||||
foo.method_experimental_text(); // ~ ERROR use of experimental item: text
|
||||
foo.trait_experimental_text(); // ~ ERROR use of experimental item: text
|
||||
|
||||
unstable(); //~ ERROR use of unstable item
|
||||
foo.method_unstable(); // ~ ERROR use of unstable item
|
||||
foo.trait_unstable(); // ~ ERROR use of unstable item
|
||||
|
||||
unstable_text(); //~ ERROR use of unstable item: text
|
||||
foo.method_unstable_text(); // ~ ERROR use of unstable item: text
|
||||
foo.trait_unstable_text(); // ~ ERROR use of unstable item: text
|
||||
|
||||
unmarked(); //~ ERROR use of unmarked item
|
||||
foo.method_unmarked(); // ~ ERROR use of unmarked item
|
||||
foo.trait_unmarked(); // ~ ERROR use of unmarked item
|
||||
|
||||
stable();
|
||||
foo.method_stable();
|
||||
foo.trait_stable();
|
||||
|
||||
stable_text();
|
||||
foo.method_stable_text();
|
||||
foo.trait_stable_text();
|
||||
|
||||
frozen();
|
||||
foo.method_frozen();
|
||||
foo.trait_frozen();
|
||||
|
||||
frozen_text();
|
||||
foo.method_frozen_text();
|
||||
foo.trait_frozen_text();
|
||||
|
||||
locked();
|
||||
foo.method_locked();
|
||||
foo.trait_locked();
|
||||
|
||||
locked_text();
|
||||
foo.method_locked_text();
|
||||
foo.trait_locked_text();
|
||||
|
||||
|
||||
let _ = DeprecatedStruct { i: 0 }; //~ ERROR use of deprecated item
|
||||
let _ = ExperimentalStruct { i: 0 }; //~ ERROR use of experimental item
|
||||
let _ = UnstableStruct { i: 0 }; //~ ERROR use of unstable item
|
||||
let _ = UnmarkedStruct { i: 0 }; //~ ERROR use of unmarked item
|
||||
let _ = StableStruct { i: 0 };
|
||||
let _ = FrozenStruct { i: 0 };
|
||||
let _ = LockedStruct { i: 0 };
|
||||
|
||||
let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item
|
||||
let _ = ExperimentalUnitStruct; //~ ERROR use of experimental item
|
||||
let _ = UnstableUnitStruct; //~ ERROR use of unstable item
|
||||
let _ = UnmarkedUnitStruct; //~ ERROR use of unmarked item
|
||||
let _ = StableUnitStruct;
|
||||
let _ = FrozenUnitStruct;
|
||||
let _ = LockedUnitStruct;
|
||||
|
||||
let _ = DeprecatedVariant; //~ ERROR use of deprecated item
|
||||
let _ = ExperimentalVariant; //~ ERROR use of experimental item
|
||||
let _ = UnstableVariant; //~ ERROR use of unstable item
|
||||
let _ = UnmarkedVariant; //~ ERROR use of unmarked item
|
||||
let _ = StableVariant;
|
||||
let _ = FrozenVariant;
|
||||
let _ = LockedVariant;
|
||||
}
|
||||
}
|
||||
|
||||
mod this_crate {
|
||||
#[deprecated]
|
||||
pub fn deprecated() {}
|
||||
#[deprecated="text"]
|
||||
pub fn deprecated_text() {}
|
||||
|
||||
#[experimental]
|
||||
pub fn experimental() {}
|
||||
#[experimental="text"]
|
||||
pub fn experimental_text() {}
|
||||
|
||||
#[unstable]
|
||||
pub fn unstable() {}
|
||||
#[unstable="text"]
|
||||
pub fn unstable_text() {}
|
||||
|
||||
pub fn unmarked() {}
|
||||
|
||||
#[stable]
|
||||
pub fn stable() {}
|
||||
#[stable="text"]
|
||||
pub fn stable_text() {}
|
||||
|
||||
#[locked]
|
||||
pub fn locked() {}
|
||||
#[locked="text"]
|
||||
pub fn locked_text() {}
|
||||
|
||||
#[frozen]
|
||||
pub fn frozen() {}
|
||||
#[frozen="text"]
|
||||
pub fn frozen_text() {}
|
||||
|
||||
#[stable]
|
||||
pub struct MethodTester;
|
||||
|
||||
impl MethodTester {
|
||||
#[deprecated]
|
||||
pub fn method_deprecated(&self) {}
|
||||
#[deprecated="text"]
|
||||
pub fn method_deprecated_text(&self) {}
|
||||
|
||||
#[experimental]
|
||||
pub fn method_experimental(&self) {}
|
||||
#[experimental="text"]
|
||||
pub fn method_experimental_text(&self) {}
|
||||
|
||||
#[unstable]
|
||||
pub fn method_unstable(&self) {}
|
||||
#[unstable="text"]
|
||||
pub fn method_unstable_text(&self) {}
|
||||
|
||||
pub fn method_unmarked(&self) {}
|
||||
|
||||
#[stable]
|
||||
pub fn method_stable(&self) {}
|
||||
#[stable="text"]
|
||||
pub fn method_stable_text(&self) {}
|
||||
|
||||
#[locked]
|
||||
pub fn method_locked(&self) {}
|
||||
#[locked="text"]
|
||||
pub fn method_locked_text(&self) {}
|
||||
|
||||
#[frozen]
|
||||
pub fn method_frozen(&self) {}
|
||||
#[frozen="text"]
|
||||
pub fn method_frozen_text(&self) {}
|
||||
}
|
||||
|
||||
pub trait Trait {
|
||||
#[deprecated]
|
||||
fn trait_deprecated(&self) {}
|
||||
#[deprecated="text"]
|
||||
fn trait_deprecated_text(&self) {}
|
||||
|
||||
#[experimental]
|
||||
fn trait_experimental(&self) {}
|
||||
#[experimental="text"]
|
||||
fn trait_experimental_text(&self) {}
|
||||
|
||||
#[unstable]
|
||||
fn trait_unstable(&self) {}
|
||||
#[unstable="text"]
|
||||
fn trait_unstable_text(&self) {}
|
||||
|
||||
fn trait_unmarked(&self) {}
|
||||
|
||||
#[stable]
|
||||
fn trait_stable(&self) {}
|
||||
#[stable="text"]
|
||||
fn trait_stable_text(&self) {}
|
||||
|
||||
#[locked]
|
||||
fn trait_locked(&self) {}
|
||||
#[locked="text"]
|
||||
fn trait_locked_text(&self) {}
|
||||
|
||||
#[frozen]
|
||||
fn trait_frozen(&self) {}
|
||||
#[frozen="text"]
|
||||
fn trait_frozen_text(&self) {}
|
||||
}
|
||||
|
||||
impl Trait for MethodTester {}
|
||||
|
||||
#[deprecated]
|
||||
pub struct DeprecatedStruct { i: int }
|
||||
#[experimental]
|
||||
pub struct ExperimentalStruct { i: int }
|
||||
#[unstable]
|
||||
pub struct UnstableStruct { i: int }
|
||||
pub struct UnmarkedStruct { i: int }
|
||||
#[stable]
|
||||
pub struct StableStruct { i: int }
|
||||
#[frozen]
|
||||
pub struct FrozenStruct { i: int }
|
||||
#[locked]
|
||||
pub struct LockedStruct { i: int }
|
||||
|
||||
#[deprecated]
|
||||
pub struct DeprecatedUnitStruct;
|
||||
#[experimental]
|
||||
pub struct ExperimentalUnitStruct;
|
||||
#[unstable]
|
||||
pub struct UnstableUnitStruct;
|
||||
pub struct UnmarkedUnitStruct;
|
||||
#[stable]
|
||||
pub struct StableUnitStruct;
|
||||
#[frozen]
|
||||
pub struct FrozenUnitStruct;
|
||||
#[locked]
|
||||
pub struct LockedUnitStruct;
|
||||
|
||||
pub enum Enum {
|
||||
#[deprecated]
|
||||
DeprecatedVariant,
|
||||
#[experimental]
|
||||
ExperimentalVariant,
|
||||
#[unstable]
|
||||
UnstableVariant,
|
||||
|
||||
UnmarkedVariant,
|
||||
#[stable]
|
||||
StableVariant,
|
||||
#[frozen]
|
||||
FrozenVariant,
|
||||
#[locked]
|
||||
LockedVariant,
|
||||
}
|
||||
|
||||
fn test() {
|
||||
let foo = MethodTester;
|
||||
|
||||
deprecated(); //~ ERROR use of deprecated item
|
||||
foo.method_deprecated(); // ~ ERROR use of deprecated item
|
||||
foo.trait_deprecated(); // ~ ERROR use of deprecated item
|
||||
|
||||
deprecated_text(); //~ ERROR use of deprecated item: text
|
||||
foo.method_deprecated_text(); // ~ ERROR use of deprecated item: text
|
||||
foo.trait_deprecated_text(); // ~ ERROR use of deprecated item: text
|
||||
|
||||
experimental(); //~ ERROR use of experimental item
|
||||
foo.method_experimental(); // ~ ERROR use of experimental item
|
||||
foo.trait_experimental(); // ~ ERROR use of experimental item
|
||||
|
||||
experimental_text(); //~ ERROR use of experimental item: text
|
||||
foo.method_experimental_text(); // ~ ERROR use of experimental item: text
|
||||
foo.trait_experimental_text(); // ~ ERROR use of experimental item: text
|
||||
|
||||
unstable(); //~ ERROR use of unstable item
|
||||
foo.method_unstable(); // ~ ERROR use of unstable item
|
||||
foo.trait_unstable(); // ~ ERROR use of unstable item
|
||||
|
||||
unstable_text(); //~ ERROR use of unstable item: text
|
||||
foo.method_unstable_text(); // ~ ERROR use of unstable item: text
|
||||
foo.trait_unstable_text(); // ~ ERROR use of unstable item: text
|
||||
|
||||
unmarked(); //~ ERROR use of unmarked item
|
||||
foo.method_unmarked(); // ~ ERROR use of unmarked item
|
||||
foo.trait_unmarked(); // ~ ERROR use of unmarked item
|
||||
|
||||
stable();
|
||||
foo.method_stable();
|
||||
foo.trait_stable();
|
||||
|
||||
stable_text();
|
||||
foo.method_stable_text();
|
||||
foo.trait_stable_text();
|
||||
|
||||
frozen();
|
||||
foo.method_frozen();
|
||||
foo.trait_frozen();
|
||||
|
||||
frozen_text();
|
||||
foo.method_frozen_text();
|
||||
foo.trait_frozen_text();
|
||||
|
||||
locked();
|
||||
foo.method_locked();
|
||||
foo.trait_locked();
|
||||
|
||||
locked_text();
|
||||
foo.method_locked_text();
|
||||
foo.trait_locked_text();
|
||||
|
||||
|
||||
let _ = DeprecatedStruct { i: 0 }; //~ ERROR use of deprecated item
|
||||
let _ = ExperimentalStruct { i: 0 }; //~ ERROR use of experimental item
|
||||
let _ = UnstableStruct { i: 0 }; //~ ERROR use of unstable item
|
||||
let _ = UnmarkedStruct { i: 0 }; //~ ERROR use of unmarked item
|
||||
let _ = StableStruct { i: 0 };
|
||||
let _ = FrozenStruct { i: 0 };
|
||||
let _ = LockedStruct { i: 0 };
|
||||
|
||||
let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item
|
||||
let _ = ExperimentalUnitStruct; //~ ERROR use of experimental item
|
||||
let _ = UnstableUnitStruct; //~ ERROR use of unstable item
|
||||
let _ = UnmarkedUnitStruct; //~ ERROR use of unmarked item
|
||||
let _ = StableUnitStruct;
|
||||
let _ = FrozenUnitStruct;
|
||||
let _ = LockedUnitStruct;
|
||||
|
||||
let _ = DeprecatedVariant; //~ ERROR use of deprecated item
|
||||
let _ = ExperimentalVariant; //~ ERROR use of experimental item
|
||||
let _ = UnstableVariant; //~ ERROR use of unstable item
|
||||
let _ = UnmarkedVariant; //~ ERROR use of unmarked item
|
||||
let _ = StableVariant;
|
||||
let _ = FrozenVariant;
|
||||
let _ = LockedVariant;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue