Rollup merge of #22803 - huonw:field-stability, r=alexcrichton
We were recording stability attributes applied to fields in the compiler, and even annotating it in the libs, but the compiler didn't actually do the checks to give errors/warnings in user crates. Details in the commit messages.
This commit is contained in:
commit
5d4e01766b
12 changed files with 575 additions and 12 deletions
|
@ -939,6 +939,7 @@ impl<'a, P: Pattern<'a>> Iterator for SplitStr<'a, P> {
|
|||
type Item = &'a str;
|
||||
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
fn next(&mut self) -> Option<&'a str> {
|
||||
Iterator::next(&mut self.0)
|
||||
}
|
||||
|
|
|
@ -1771,6 +1771,11 @@ impl LintPass for Stability {
|
|||
stability::check_path(cx.tcx, path, id,
|
||||
&mut |id, sp, stab| self.lint(cx, id, sp, stab));
|
||||
}
|
||||
|
||||
fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
|
||||
stability::check_pat(cx.tcx, pat,
|
||||
&mut |id, sp, stab| self.lint(cx, id, sp, stab))
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
|
|
|
@ -58,8 +58,10 @@ impl<'a> Annotator<'a> {
|
|||
attrs: &Vec<Attribute>, item_sp: Span, f: F, required: bool) where
|
||||
F: FnOnce(&mut Annotator),
|
||||
{
|
||||
debug!("annotate(id = {:?}, attrs = {:?})", id, attrs);
|
||||
match attr::find_stability(self.sess.diagnostic(), attrs, item_sp) {
|
||||
Some(stab) => {
|
||||
debug!("annotate: found {:?}", stab);
|
||||
self.index.local.insert(id, stab.clone());
|
||||
|
||||
// Don't inherit #[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -72,6 +74,8 @@ impl<'a> Annotator<'a> {
|
|||
}
|
||||
}
|
||||
None => {
|
||||
debug!("annotate: not found, use_parent = {:?}, parent = {:?}",
|
||||
use_parent, self.parent);
|
||||
if use_parent {
|
||||
if let Some(stab) = self.parent.clone() {
|
||||
self.index.local.insert(id, stab);
|
||||
|
@ -299,6 +303,12 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
|
|||
&mut |id, sp, stab| self.check(id, sp, stab));
|
||||
visit::walk_path(self, path)
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, pat: &ast::Pat) {
|
||||
check_pat(self.tcx, pat,
|
||||
&mut |id, sp, stab| self.check(id, sp, stab));
|
||||
visit::walk_pat(self, pat)
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper for discovering nodes to check for stability
|
||||
|
@ -385,6 +395,76 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
|
|||
None => return
|
||||
}
|
||||
}
|
||||
ast::ExprField(ref base_e, ref field) => {
|
||||
span = field.span;
|
||||
match ty::expr_ty_adjusted(tcx, base_e).sty {
|
||||
ty::ty_struct(did, _) => {
|
||||
ty::lookup_struct_fields(tcx, did)
|
||||
.iter()
|
||||
.find(|f| f.name == field.node.name)
|
||||
.unwrap_or_else(|| {
|
||||
tcx.sess.span_bug(field.span,
|
||||
"stability::check_expr: unknown named field access")
|
||||
})
|
||||
.id
|
||||
}
|
||||
_ => tcx.sess.span_bug(e.span,
|
||||
"stability::check_expr: named field access on non-struct")
|
||||
}
|
||||
}
|
||||
ast::ExprTupField(ref base_e, ref field) => {
|
||||
span = field.span;
|
||||
match ty::expr_ty_adjusted(tcx, base_e).sty {
|
||||
ty::ty_struct(did, _) => {
|
||||
ty::lookup_struct_fields(tcx, did)
|
||||
.get(field.node)
|
||||
.unwrap_or_else(|| {
|
||||
tcx.sess.span_bug(field.span,
|
||||
"stability::check_expr: unknown unnamed field access")
|
||||
})
|
||||
.id
|
||||
}
|
||||
ty::ty_tup(..) => return,
|
||||
_ => tcx.sess.span_bug(e.span,
|
||||
"stability::check_expr: unnamed field access on \
|
||||
something other than a tuple or struct")
|
||||
}
|
||||
}
|
||||
ast::ExprStruct(_, ref expr_fields, _) => {
|
||||
let type_ = ty::expr_ty(tcx, e);
|
||||
match type_.sty {
|
||||
ty::ty_struct(did, _) => {
|
||||
let struct_fields = ty::lookup_struct_fields(tcx, did);
|
||||
// check the stability of each field that appears
|
||||
// in the construction expression.
|
||||
for field in expr_fields {
|
||||
let did = struct_fields
|
||||
.iter()
|
||||
.find(|f| f.name == field.ident.node.name)
|
||||
.unwrap_or_else(|| {
|
||||
tcx.sess.span_bug(field.span,
|
||||
"stability::check_expr: unknown named \
|
||||
field access")
|
||||
})
|
||||
.id;
|
||||
maybe_do_stability_check(tcx, did, field.span, cb);
|
||||
}
|
||||
|
||||
// we're done.
|
||||
return
|
||||
}
|
||||
// we don't look at stability attributes on
|
||||
// struct-like enums (yet...), but it's definitely not
|
||||
// a bug to have construct one.
|
||||
ty::ty_enum(..) => return,
|
||||
_ => {
|
||||
tcx.sess.span_bug(e.span,
|
||||
&format!("stability::check_expr: struct construction \
|
||||
of non-struct, type {:?}",
|
||||
type_.repr(tcx)));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => return
|
||||
};
|
||||
|
||||
|
@ -403,6 +483,47 @@ pub fn check_path(tcx: &ty::ctxt, path: &ast::Path, id: ast::NodeId,
|
|||
|
||||
}
|
||||
|
||||
pub fn check_pat(tcx: &ty::ctxt, pat: &ast::Pat,
|
||||
cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
|
||||
debug!("check_pat(pat = {:?})", pat);
|
||||
if is_internal(tcx, pat.span) { return; }
|
||||
|
||||
let did = match ty::pat_ty_opt(tcx, pat) {
|
||||
Some(&ty::TyS { sty: ty::ty_struct(did, _), .. }) => did,
|
||||
Some(_) | None => return,
|
||||
};
|
||||
let struct_fields = ty::lookup_struct_fields(tcx, did);
|
||||
match pat.node {
|
||||
// Foo(a, b, c)
|
||||
ast::PatEnum(_, Some(ref pat_fields)) => {
|
||||
for (field, struct_field) in pat_fields.iter().zip(struct_fields.iter()) {
|
||||
// a .. pattern is fine, but anything positional is
|
||||
// not.
|
||||
if let ast::PatWild(ast::PatWildMulti) = field.node {
|
||||
continue
|
||||
}
|
||||
maybe_do_stability_check(tcx, struct_field.id, field.span, cb)
|
||||
}
|
||||
}
|
||||
// Foo { a, b, c }
|
||||
ast::PatStruct(_, ref pat_fields, _) => {
|
||||
for field in pat_fields {
|
||||
let did = struct_fields
|
||||
.iter()
|
||||
.find(|f| f.name == field.node.ident.name)
|
||||
.unwrap_or_else(|| {
|
||||
tcx.sess.span_bug(field.span,
|
||||
"stability::check_pat: unknown named field access")
|
||||
})
|
||||
.id;
|
||||
maybe_do_stability_check(tcx, did, field.span, cb);
|
||||
}
|
||||
}
|
||||
// everything else is fine.
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_do_stability_check(tcx: &ty::ctxt, id: ast::DefId, span: Span,
|
||||
cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
|
||||
if !is_staged_api(tcx, id) { return }
|
||||
|
|
|
@ -4298,6 +4298,9 @@ pub fn free_region_from_def(outlives_extent: region::DestructionScopeData,
|
|||
pub fn pat_ty<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Ty<'tcx> {
|
||||
return node_id_to_type(cx, pat.id);
|
||||
}
|
||||
pub fn pat_ty_opt<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Option<Ty<'tcx>> {
|
||||
return node_id_to_type_opt(cx, pat.id);
|
||||
}
|
||||
|
||||
|
||||
// Returns the type of an expression as a monotype.
|
||||
|
|
|
@ -233,6 +233,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
|||
ast::ItemEnum(ref def, _) if public_first => {
|
||||
for variant in &def.variants {
|
||||
self.exported_items.insert(variant.node.id);
|
||||
self.public_items.insert(variant.node.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,6 +322,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
|||
Some(id) => { self.exported_items.insert(id); }
|
||||
None => {}
|
||||
}
|
||||
// fields can be public or private, so lets check
|
||||
for field in &def.fields {
|
||||
let vis = match field.node.kind {
|
||||
ast::NamedField(_, vis) | ast::UnnamedField(vis) => vis
|
||||
};
|
||||
if vis == ast::Public {
|
||||
self.public_items.insert(field.node.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ast::ItemTy(ref ty, _) if public_first => {
|
||||
|
|
|
@ -102,6 +102,7 @@ impl MemWriter {
|
|||
|
||||
impl Writer for MemWriter {
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
self.buf.push_all(buf);
|
||||
Ok(())
|
||||
|
|
|
@ -384,7 +384,7 @@ impl<T> !Sync for SyncSender<T> {}
|
|||
/// contains the data being sent as a payload so it can be recovered.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub struct SendError<T>(pub T);
|
||||
pub struct SendError<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
|
||||
|
||||
/// An error returned from the `recv` function on a `Receiver`.
|
||||
///
|
||||
|
|
|
@ -105,10 +105,12 @@ pub struct Key<T> {
|
|||
// This is trivially devirtualizable by LLVM because we never store anything
|
||||
// to this field and rustc can declare the `static` as constant as well.
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "thread_local_internals")]
|
||||
pub inner: fn() -> &'static __impl::KeyInner<UnsafeCell<Option<T>>>,
|
||||
|
||||
// initialization routine to invoke to create a value
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "thread_local_internals")]
|
||||
pub init: fn() -> T,
|
||||
}
|
||||
|
||||
|
|
|
@ -100,14 +100,22 @@ pub trait UnstableTrait { fn dummy(&self) { } }
|
|||
|
||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
pub struct DeprecatedStruct { pub i: int }
|
||||
pub struct DeprecatedStruct {
|
||||
#[stable(feature = "test_feature", since = "1.0.0")] pub i: int
|
||||
}
|
||||
#[unstable(feature = "test_feature")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
pub struct DeprecatedUnstableStruct { pub i: int }
|
||||
pub struct DeprecatedUnstableStruct {
|
||||
#[stable(feature = "test_feature", since = "1.0.0")] pub i: int
|
||||
}
|
||||
#[unstable(feature = "test_feature")]
|
||||
pub struct UnstableStruct { pub i: int }
|
||||
pub struct UnstableStruct {
|
||||
#[stable(feature = "test_feature", since = "1.0.0")] pub i: int
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct StableStruct { pub i: int }
|
||||
pub struct StableStruct {
|
||||
#[stable(feature = "test_feature", since = "1.0.0")] pub i: int
|
||||
}
|
||||
|
||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
|
@ -137,14 +145,14 @@ pub enum Enum {
|
|||
|
||||
#[stable(feature = "test_feature", since = "1.0.0")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
pub struct DeprecatedTupleStruct(pub int);
|
||||
pub struct DeprecatedTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub int);
|
||||
#[unstable(feature = "test_feature")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
pub struct DeprecatedUnstableTupleStruct(pub int);
|
||||
pub struct DeprecatedUnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub int);
|
||||
#[unstable(feature = "test_feature")]
|
||||
pub struct UnstableTupleStruct(pub int);
|
||||
pub struct UnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub int);
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct StableTupleStruct(pub int);
|
||||
pub struct StableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub int);
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! macro_test {
|
||||
|
|
60
src/test/auxiliary/lint_stability_fields.rs
Normal file
60
src/test/auxiliary/lint_stability_fields.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Copyright 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.
|
||||
|
||||
#![feature(staged_api)]
|
||||
#![staged_api]
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Stable {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub inherit: u8, // it's a lie (stable doesn't inherit)
|
||||
#[unstable(feature = "test_feature")]
|
||||
pub override1: u8,
|
||||
#[deprecated(since = "1.0.0")]
|
||||
#[unstable(feature = "test_feature")]
|
||||
pub override2: u8,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Stable2(#[stable(feature = "rust1", since = "1.0.0")] pub u8,
|
||||
#[unstable(feature = "test_feature")] pub u8,
|
||||
#[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] pub u8);
|
||||
|
||||
#[unstable(feature = "test_feature")]
|
||||
pub struct Unstable {
|
||||
pub inherit: u8,
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub override1: u8,
|
||||
#[deprecated(since = "1.0.0")]
|
||||
#[unstable(feature = "test_feature")]
|
||||
pub override2: u8,
|
||||
}
|
||||
|
||||
#[unstable(feature = "test_feature")]
|
||||
pub struct Unstable2(pub u8,
|
||||
#[stable(feature = "rust1", since = "1.0.0")] pub u8,
|
||||
#[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] pub u8);
|
||||
|
||||
#[unstable(feature = "test_feature")]
|
||||
#[deprecated(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Deprecated {
|
||||
pub inherit: u8,
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub override1: u8,
|
||||
#[unstable(feature = "test_feature")]
|
||||
pub override2: u8,
|
||||
}
|
||||
|
||||
#[unstable(feature = "test_feature")]
|
||||
#[deprecated(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Deprecated2(pub u8,
|
||||
#[stable(feature = "rust1", since = "1.0.0")] pub u8,
|
||||
#[unstable(feature = "test_feature")] pub u8);
|
346
src/test/compile-fail/lint-stability-fields.rs
Normal file
346
src/test/compile-fail/lint-stability-fields.rs
Normal file
|
@ -0,0 +1,346 @@
|
|||
// Copyright 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.
|
||||
|
||||
// aux-build:lint_stability_fields.rs
|
||||
#![deny(deprecated)]
|
||||
#![allow(dead_code)]
|
||||
#![feature(staged_api)]
|
||||
#![staged_api]
|
||||
|
||||
mod cross_crate {
|
||||
extern crate lint_stability_fields;
|
||||
|
||||
use self::lint_stability_fields::*;
|
||||
|
||||
pub fn foo() {
|
||||
let x = Stable {
|
||||
inherit: 1,
|
||||
override1: 2, //~ WARN use of unstable
|
||||
override2: 3,
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
};
|
||||
|
||||
let _ = x.inherit;
|
||||
let _ = x.override1; //~ WARN use of unstable
|
||||
let _ = x.override2;
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
|
||||
let Stable {
|
||||
inherit: _,
|
||||
override1: _, //~ WARN use of unstable
|
||||
override2: _
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
} = x;
|
||||
// all fine
|
||||
let Stable { .. } = x;
|
||||
|
||||
let x = Stable2(1, 2, 3);
|
||||
|
||||
let _ = x.0;
|
||||
let _ = x.1; //~ WARN use of unstable
|
||||
let _ = x.2;
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
|
||||
let Stable2(_,
|
||||
_, //~ WARN use of unstable
|
||||
_)
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
= x;
|
||||
// all fine
|
||||
let Stable2(..) = x;
|
||||
|
||||
|
||||
let x = Unstable { //~ WARN use of unstable
|
||||
inherit: 1, //~ WARN use of unstable
|
||||
override1: 2,
|
||||
override2: 3,
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
};
|
||||
|
||||
let _ = x.inherit; //~ WARN use of unstable
|
||||
let _ = x.override1;
|
||||
let _ = x.override2;
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
|
||||
let Unstable { //~ WARN use of unstable
|
||||
inherit: _, //~ WARN use of unstable
|
||||
override1: _,
|
||||
override2: _
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
} = x;
|
||||
|
||||
let Unstable //~ WARN use of unstable
|
||||
// the patterns are all fine:
|
||||
{ .. } = x;
|
||||
|
||||
|
||||
let x = Unstable2(1, 2, 3); //~ WARN use of unstable
|
||||
|
||||
let _ = x.0; //~ WARN use of unstable
|
||||
let _ = x.1;
|
||||
let _ = x.2;
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
|
||||
let Unstable2 //~ WARN use of unstable
|
||||
(_, //~ WARN use of unstable
|
||||
_,
|
||||
_)
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
= x;
|
||||
let Unstable2 //~ WARN use of unstable
|
||||
// the patterns are all fine:
|
||||
(..) = x;
|
||||
|
||||
|
||||
let x = Deprecated {
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
inherit: 1,
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
override1: 2,
|
||||
override2: 3, //~ WARN use of unstable
|
||||
};
|
||||
|
||||
let _ = x.inherit;
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
let _ = x.override1;
|
||||
let _ = x.override2; //~ WARN use of unstable
|
||||
|
||||
let Deprecated {
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
inherit: _,
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
override1: _,
|
||||
override2: _ //~ WARN use of unstable
|
||||
} = x;
|
||||
|
||||
let Deprecated
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
// the patterns are all fine:
|
||||
{ .. } = x;
|
||||
|
||||
let x = Deprecated2(1, 2, 3);
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
|
||||
let _ = x.0;
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
let _ = x.1;
|
||||
let _ = x.2; //~ WARN use of unstable
|
||||
|
||||
let Deprecated2
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
(_,
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
_,
|
||||
_) //~ WARN use of unstable
|
||||
= x;
|
||||
let Deprecated2
|
||||
//~^ ERROR use of deprecated item
|
||||
//~^^ WARN use of unstable
|
||||
// the patterns are all fine:
|
||||
(..) = x;
|
||||
}
|
||||
}
|
||||
|
||||
mod this_crate {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
struct Stable {
|
||||
inherit: u8,
|
||||
#[unstable(feature = "test_feature")]
|
||||
override1: u8,
|
||||
#[deprecated(since = "1.0.0")]
|
||||
#[unstable(feature = "test_feature")]
|
||||
override2: u8,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
struct Stable2(u8,
|
||||
#[stable(feature = "rust1", since = "1.0.0")] u8,
|
||||
#[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] u8);
|
||||
|
||||
#[unstable(feature = "test_feature")]
|
||||
struct Unstable {
|
||||
inherit: u8,
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
override1: u8,
|
||||
#[deprecated(since = "1.0.0")]
|
||||
#[unstable(feature = "test_feature")]
|
||||
override2: u8,
|
||||
}
|
||||
|
||||
#[unstable(feature = "test_feature")]
|
||||
struct Unstable2(u8,
|
||||
#[stable(feature = "rust1", since = "1.0.0")] u8,
|
||||
#[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] u8);
|
||||
|
||||
#[unstable(feature = "test_feature")]
|
||||
#[deprecated(feature = "rust1", since = "1.0.0")]
|
||||
struct Deprecated {
|
||||
inherit: u8,
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
override1: u8,
|
||||
#[unstable(feature = "test_feature")]
|
||||
override2: u8,
|
||||
}
|
||||
|
||||
#[unstable(feature = "test_feature")]
|
||||
#[deprecated(feature = "rust1", since = "1.0.0")]
|
||||
struct Deprecated2(u8,
|
||||
#[stable(feature = "rust1", since = "1.0.0")] u8,
|
||||
#[unstable(feature = "test_feature")] u8);
|
||||
|
||||
pub fn foo() {
|
||||
let x = Stable {
|
||||
inherit: 1,
|
||||
override1: 2,
|
||||
override2: 3,
|
||||
//~^ ERROR use of deprecated item
|
||||
};
|
||||
|
||||
let _ = x.inherit;
|
||||
let _ = x.override1;
|
||||
let _ = x.override2;
|
||||
//~^ ERROR use of deprecated item
|
||||
|
||||
let Stable {
|
||||
inherit: _,
|
||||
override1: _,
|
||||
override2: _
|
||||
//~^ ERROR use of deprecated item
|
||||
} = x;
|
||||
// all fine
|
||||
let Stable { .. } = x;
|
||||
|
||||
let x = Stable2(1, 2, 3);
|
||||
|
||||
let _ = x.0;
|
||||
let _ = x.1;
|
||||
let _ = x.2;
|
||||
//~^ ERROR use of deprecated item
|
||||
|
||||
let Stable2(_,
|
||||
_,
|
||||
_)
|
||||
//~^ ERROR use of deprecated item
|
||||
= x;
|
||||
// all fine
|
||||
let Stable2(..) = x;
|
||||
|
||||
|
||||
let x = Unstable {
|
||||
inherit: 1,
|
||||
override1: 2,
|
||||
override2: 3,
|
||||
//~^ ERROR use of deprecated item
|
||||
};
|
||||
|
||||
let _ = x.inherit;
|
||||
let _ = x.override1;
|
||||
let _ = x.override2;
|
||||
//~^ ERROR use of deprecated item
|
||||
|
||||
let Unstable {
|
||||
inherit: _,
|
||||
override1: _,
|
||||
override2: _
|
||||
//~^ ERROR use of deprecated item
|
||||
} = x;
|
||||
|
||||
let Unstable
|
||||
// the patterns are all fine:
|
||||
{ .. } = x;
|
||||
|
||||
|
||||
let x = Unstable2(1, 2, 3);
|
||||
|
||||
let _ = x.0;
|
||||
let _ = x.1;
|
||||
let _ = x.2;
|
||||
//~^ ERROR use of deprecated item
|
||||
|
||||
let Unstable2
|
||||
(_,
|
||||
_,
|
||||
_)
|
||||
//~^ ERROR use of deprecated item
|
||||
= x;
|
||||
let Unstable2
|
||||
// the patterns are all fine:
|
||||
(..) = x;
|
||||
|
||||
|
||||
let x = Deprecated {
|
||||
//~^ ERROR use of deprecated item
|
||||
inherit: 1,
|
||||
//~^ ERROR use of deprecated item
|
||||
override1: 2,
|
||||
override2: 3,
|
||||
};
|
||||
|
||||
let _ = x.inherit;
|
||||
//~^ ERROR use of deprecated item
|
||||
let _ = x.override1;
|
||||
let _ = x.override2;
|
||||
|
||||
let Deprecated {
|
||||
//~^ ERROR use of deprecated item
|
||||
inherit: _,
|
||||
//~^ ERROR use of deprecated item
|
||||
override1: _,
|
||||
override2: _
|
||||
} = x;
|
||||
|
||||
let Deprecated
|
||||
//~^ ERROR use of deprecated item
|
||||
// the patterns are all fine:
|
||||
{ .. } = x;
|
||||
|
||||
let x = Deprecated2(1, 2, 3);
|
||||
//~^ ERROR use of deprecated item
|
||||
|
||||
let _ = x.0;
|
||||
//~^ ERROR use of deprecated item
|
||||
let _ = x.1;
|
||||
let _ = x.2;
|
||||
|
||||
let Deprecated2
|
||||
//~^ ERROR use of deprecated item
|
||||
(_,
|
||||
//~^ ERROR use of deprecated item
|
||||
_,
|
||||
_)
|
||||
= x;
|
||||
let Deprecated2
|
||||
//~^ ERROR use of deprecated item
|
||||
// the patterns are all fine:
|
||||
(..) = x;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -317,11 +317,17 @@ mod this_crate {
|
|||
|
||||
#[unstable(feature = "test_feature")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
pub struct DeprecatedStruct { i: isize }
|
||||
pub struct DeprecatedStruct {
|
||||
#[stable(feature = "test_feature", since = "1.0.0")] i: isize
|
||||
}
|
||||
#[unstable(feature = "test_feature")]
|
||||
pub struct UnstableStruct { i: isize }
|
||||
pub struct UnstableStruct {
|
||||
#[stable(feature = "test_feature", since = "1.0.0")] i: isize
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct StableStruct { i: isize }
|
||||
pub struct StableStruct {
|
||||
#[stable(feature = "test_feature", since = "1.0.0")] i: isize
|
||||
}
|
||||
|
||||
#[unstable(feature = "test_feature")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
|
|
Loading…
Add table
Reference in a new issue