Auto merge of #50345 - kennytm:rollup, r=kennytm
Rollup of 7 pull requests Successful merges: - #50233 (Make `Vec::new` a `const fn`) - #50312 (Add more links in panic docs) - #50316 (Fix some broken links in docs.) - #50325 (Add a few more tests for proc macro feature gating) - #50327 (Display correct unused field suggestion for nested struct patterns) - #50330 (check that #[used] is used only on statics) - #50344 (Update Cargo to 2018-04-28 122fd5be5201913d42e219e132d6569493583bca) Failed merges:
This commit is contained in:
@@ -124,6 +124,7 @@
|
|||||||
#![feature(pointer_methods)]
|
#![feature(pointer_methods)]
|
||||||
#![feature(inclusive_range_fields)]
|
#![feature(inclusive_range_fields)]
|
||||||
#![cfg_attr(stage0, feature(generic_param_attrs))]
|
#![cfg_attr(stage0, feature(generic_param_attrs))]
|
||||||
|
#![feature(rustc_const_unstable)]
|
||||||
|
|
||||||
#![cfg_attr(not(test), feature(fn_traits, i128))]
|
#![cfg_attr(not(test), feature(fn_traits, i128))]
|
||||||
#![cfg_attr(test, feature(test))]
|
#![cfg_attr(test, feature(test))]
|
||||||
|
|||||||
@@ -56,14 +56,16 @@ pub struct RawVec<T, A: Alloc = Global> {
|
|||||||
impl<T, A: Alloc> RawVec<T, A> {
|
impl<T, A: Alloc> RawVec<T, A> {
|
||||||
/// Like `new` but parameterized over the choice of allocator for
|
/// Like `new` but parameterized over the choice of allocator for
|
||||||
/// the returned RawVec.
|
/// the returned RawVec.
|
||||||
pub fn new_in(a: A) -> Self {
|
pub const fn new_in(a: A) -> Self {
|
||||||
// !0 is usize::MAX. This branch should be stripped at compile time.
|
// !0 is usize::MAX. This branch should be stripped at compile time.
|
||||||
let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
|
// FIXME(mark-i-m): use this line when `if`s are allowed in `const`
|
||||||
|
//let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
|
||||||
|
|
||||||
// Unique::empty() doubles as "unallocated" and "zero-sized allocation"
|
// Unique::empty() doubles as "unallocated" and "zero-sized allocation"
|
||||||
RawVec {
|
RawVec {
|
||||||
ptr: Unique::empty(),
|
ptr: Unique::empty(),
|
||||||
cap,
|
// FIXME(mark-i-m): use `cap` when ifs are allowed in const
|
||||||
|
cap: [0, !0][(mem::size_of::<T>() == 0) as usize],
|
||||||
a,
|
a,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +122,7 @@ impl<T> RawVec<T, Global> {
|
|||||||
/// RawVec with capacity 0. If T has 0 size, then it makes a
|
/// RawVec with capacity 0. If T has 0 size, then it makes a
|
||||||
/// RawVec with capacity `usize::MAX`. Useful for implementing
|
/// RawVec with capacity `usize::MAX`. Useful for implementing
|
||||||
/// delayed allocation.
|
/// delayed allocation.
|
||||||
pub fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self::new_in(Global)
|
Self::new_in(Global)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -322,7 +322,8 @@ impl<T> Vec<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn new() -> Vec<T> {
|
#[rustc_const_unstable(feature = "const_vec_new")]
|
||||||
|
pub const fn new() -> Vec<T> {
|
||||||
Vec {
|
Vec {
|
||||||
buf: RawVec::new(),
|
buf: RawVec::new(),
|
||||||
len: 0,
|
len: 0,
|
||||||
|
|||||||
@@ -1094,6 +1094,8 @@ pub trait Iterator {
|
|||||||
/// `flatten()` a three-dimensional array the result will be
|
/// `flatten()` a three-dimensional array the result will be
|
||||||
/// two-dimensional and not one-dimensional. To get a one-dimensional
|
/// two-dimensional and not one-dimensional. To get a one-dimensional
|
||||||
/// structure, you have to `flatten()` again.
|
/// structure, you have to `flatten()` again.
|
||||||
|
///
|
||||||
|
/// [`flat_map()`]: #method.flat_map
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "iterator_flatten", issue = "48213")]
|
#[unstable(feature = "iterator_flatten", issue = "48213")]
|
||||||
fn flatten(self) -> Flatten<Self>
|
fn flatten(self) -> Flatten<Self>
|
||||||
|
|||||||
@@ -602,6 +602,8 @@ unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}
|
|||||||
/// `Pin` pointer.
|
/// `Pin` pointer.
|
||||||
///
|
///
|
||||||
/// This trait is automatically implemented for almost every type.
|
/// This trait is automatically implemented for almost every type.
|
||||||
|
///
|
||||||
|
/// [`Pin`]: ../mem/struct.Pin.html
|
||||||
#[unstable(feature = "pin", issue = "49150")]
|
#[unstable(feature = "pin", issue = "49150")]
|
||||||
pub unsafe auto trait Unpin {}
|
pub unsafe auto trait Unpin {}
|
||||||
|
|
||||||
|
|||||||
@@ -2552,10 +2552,9 @@ impl<T: Sized> Unique<T> {
|
|||||||
/// This is useful for initializing types which lazily allocate, like
|
/// This is useful for initializing types which lazily allocate, like
|
||||||
/// `Vec::new` does.
|
/// `Vec::new` does.
|
||||||
// FIXME: rename to dangling() to match NonNull?
|
// FIXME: rename to dangling() to match NonNull?
|
||||||
pub fn empty() -> Self {
|
pub const fn empty() -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = mem::align_of::<T>() as *mut T;
|
Unique::new_unchecked(mem::align_of::<T>() as *mut T)
|
||||||
Unique::new_unchecked(ptr)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ enum Target {
|
|||||||
Expression,
|
Expression,
|
||||||
Statement,
|
Statement,
|
||||||
Closure,
|
Closure,
|
||||||
|
Static,
|
||||||
Other,
|
Other,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,6 +44,7 @@ impl Target {
|
|||||||
hir::ItemEnum(..) => Target::Enum,
|
hir::ItemEnum(..) => Target::Enum,
|
||||||
hir::ItemConst(..) => Target::Const,
|
hir::ItemConst(..) => Target::Const,
|
||||||
hir::ItemForeignMod(..) => Target::ForeignMod,
|
hir::ItemForeignMod(..) => Target::ForeignMod,
|
||||||
|
hir::ItemStatic(..) => Target::Static,
|
||||||
_ => Target::Other,
|
_ => Target::Other,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,6 +104,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.check_repr(item, target);
|
self.check_repr(item, target);
|
||||||
|
self.check_used(item, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if an `#[inline]` is applied to a function or a closure.
|
/// Check if an `#[inline]` is applied to a function or a closure.
|
||||||
@@ -305,6 +308,15 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_used(&self, item: &hir::Item, target: Target) {
|
||||||
|
for attr in &item.attrs {
|
||||||
|
if attr.name().map(|name| name == "used").unwrap_or(false) && target != Target::Static {
|
||||||
|
self.tcx.sess
|
||||||
|
.span_err(attr.span, "attribute must be applied to a `static` variable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Visitor<'tcx> for CheckAttrVisitor<'a, 'tcx> {
|
impl<'a, 'tcx> Visitor<'tcx> for CheckAttrVisitor<'a, 'tcx> {
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ use ty::{self, TyCtxt};
|
|||||||
use lint;
|
use lint;
|
||||||
use util::nodemap::{NodeMap, NodeSet};
|
use util::nodemap::{NodeMap, NodeSet};
|
||||||
|
|
||||||
|
use std::collections::VecDeque;
|
||||||
use std::{fmt, usize};
|
use std::{fmt, usize};
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::io;
|
use std::io;
|
||||||
@@ -412,20 +413,45 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
|
fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
|
||||||
for pat in &arm.pats {
|
for mut pat in &arm.pats {
|
||||||
// for struct patterns, take note of which fields used shorthand (`x` rather than `x: x`)
|
// For struct patterns, take note of which fields used shorthand
|
||||||
|
// (`x` rather than `x: x`).
|
||||||
//
|
//
|
||||||
// FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be phased
|
// FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be
|
||||||
// out in favor of `HirId`s; however, we need to match the signature of `each_binding`,
|
// phased out in favor of `HirId`s; however, we need to match the signature of
|
||||||
// which uses `NodeIds`.
|
// `each_binding`, which uses `NodeIds`.
|
||||||
let mut shorthand_field_ids = NodeSet();
|
let mut shorthand_field_ids = NodeSet();
|
||||||
if let hir::PatKind::Struct(_, ref fields, _) = pat.node {
|
let mut pats = VecDeque::new();
|
||||||
|
pats.push_back(pat);
|
||||||
|
while let Some(pat) = pats.pop_front() {
|
||||||
|
use hir::PatKind::*;
|
||||||
|
match pat.node {
|
||||||
|
Binding(_, _, _, ref inner_pat) => {
|
||||||
|
pats.extend(inner_pat.iter());
|
||||||
|
}
|
||||||
|
Struct(_, ref fields, _) => {
|
||||||
for field in fields {
|
for field in fields {
|
||||||
if field.node.is_shorthand {
|
if field.node.is_shorthand {
|
||||||
shorthand_field_ids.insert(field.node.pat.id);
|
shorthand_field_ids.insert(field.node.pat.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ref(ref inner_pat, _) |
|
||||||
|
Box(ref inner_pat) => {
|
||||||
|
pats.push_back(inner_pat);
|
||||||
|
}
|
||||||
|
TupleStruct(_, ref inner_pats, _) |
|
||||||
|
Tuple(ref inner_pats, _) => {
|
||||||
|
pats.extend(inner_pats.iter());
|
||||||
|
}
|
||||||
|
Slice(ref pre_pats, ref inner_pat, ref post_pats) => {
|
||||||
|
pats.extend(pre_pats.iter());
|
||||||
|
pats.extend(inner_pat.iter());
|
||||||
|
pats.extend(post_pats.iter());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pat.each_binding(|bm, p_id, sp, path1| {
|
pat.each_binding(|bm, p_id, sp, path1| {
|
||||||
debug!("adding local variable {} from match with bm {:?}",
|
debug!("adding local variable {} from match with bm {:?}",
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ impl TaggedHashUintPtr {
|
|||||||
///
|
///
|
||||||
/// Essential invariants of this structure:
|
/// Essential invariants of this structure:
|
||||||
///
|
///
|
||||||
/// - if t.hashes[i] == EMPTY_BUCKET, then `Bucket::at_index(&t, i).raw`
|
/// - if `t.hashes[i] == EMPTY_BUCKET`, then `Bucket::at_index(&t, i).raw`
|
||||||
/// points to 'undefined' contents. Don't read from it. This invariant is
|
/// points to 'undefined' contents. Don't read from it. This invariant is
|
||||||
/// enforced outside this module with the `EmptyBucket`, `FullBucket`,
|
/// enforced outside this module with the `EmptyBucket`, `FullBucket`,
|
||||||
/// and `SafeHash` types.
|
/// and `SafeHash` types.
|
||||||
|
|||||||
@@ -1118,6 +1118,7 @@ impl CStr {
|
|||||||
///
|
///
|
||||||
/// [`Cow`]: ../borrow/enum.Cow.html
|
/// [`Cow`]: ../borrow/enum.Cow.html
|
||||||
/// [`Borrowed`]: ../borrow/enum.Cow.html#variant.Borrowed
|
/// [`Borrowed`]: ../borrow/enum.Cow.html#variant.Borrowed
|
||||||
|
/// [`Owned`]: ../borrow/enum.Cow.html#variant.Owned
|
||||||
/// [`str`]: ../primitive.str.html
|
/// [`str`]: ../primitive.str.html
|
||||||
/// [`String`]: ../string/struct.String.html
|
/// [`String`]: ../string/struct.String.html
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -31,10 +31,14 @@ pub use core::panic::{PanicInfo, Location};
|
|||||||
/// A marker trait which represents "panic safe" types in Rust.
|
/// A marker trait which represents "panic safe" types in Rust.
|
||||||
///
|
///
|
||||||
/// This trait is implemented by default for many types and behaves similarly in
|
/// This trait is implemented by default for many types and behaves similarly in
|
||||||
/// terms of inference of implementation to the `Send` and `Sync` traits. The
|
/// terms of inference of implementation to the [`Send`] and [`Sync`] traits. The
|
||||||
/// purpose of this trait is to encode what types are safe to cross a `catch_unwind`
|
/// purpose of this trait is to encode what types are safe to cross a [`catch_unwind`]
|
||||||
/// boundary with no fear of unwind safety.
|
/// boundary with no fear of unwind safety.
|
||||||
///
|
///
|
||||||
|
/// [`Send`]: ../marker/trait.Send.html
|
||||||
|
/// [`Sync`]: ../marker/trait.Sync.html
|
||||||
|
/// [`catch_unwind`]: ./fn.catch_unwind.html
|
||||||
|
///
|
||||||
/// ## What is unwind safety?
|
/// ## What is unwind safety?
|
||||||
///
|
///
|
||||||
/// In Rust a function can "return" early if it either panics or calls a
|
/// In Rust a function can "return" early if it either panics or calls a
|
||||||
@@ -95,12 +99,13 @@ pub use core::panic::{PanicInfo, Location};
|
|||||||
///
|
///
|
||||||
/// ## When should `UnwindSafe` be used?
|
/// ## When should `UnwindSafe` be used?
|
||||||
///
|
///
|
||||||
/// Is not intended that most types or functions need to worry about this trait.
|
/// It is not intended that most types or functions need to worry about this trait.
|
||||||
/// It is only used as a bound on the `catch_unwind` function and as mentioned above,
|
/// It is only used as a bound on the `catch_unwind` function and as mentioned
|
||||||
/// the lack of `unsafe` means it is mostly an advisory. The `AssertUnwindSafe`
|
/// above, the lack of `unsafe` means it is mostly an advisory. The
|
||||||
/// wrapper struct in this module can be used to force this trait to be
|
/// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be
|
||||||
/// implemented for any closed over variables passed to the `catch_unwind` function
|
/// implemented for any closed over variables passed to `catch_unwind`.
|
||||||
/// (more on this below).
|
///
|
||||||
|
/// [`AssertUnwindSafe`]: ./struct.AssertUnwindSafe.html
|
||||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||||
#[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
|
#[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
|
||||||
across an unwind boundary"]
|
across an unwind boundary"]
|
||||||
@@ -109,11 +114,14 @@ pub auto trait UnwindSafe {}
|
|||||||
/// A marker trait representing types where a shared reference is considered
|
/// A marker trait representing types where a shared reference is considered
|
||||||
/// unwind safe.
|
/// unwind safe.
|
||||||
///
|
///
|
||||||
/// This trait is namely not implemented by `UnsafeCell`, the root of all
|
/// This trait is namely not implemented by [`UnsafeCell`], the root of all
|
||||||
/// interior mutability.
|
/// interior mutability.
|
||||||
///
|
///
|
||||||
/// This is a "helper marker trait" used to provide impl blocks for the
|
/// This is a "helper marker trait" used to provide impl blocks for the
|
||||||
/// `UnwindSafe` trait, for more information see that documentation.
|
/// [`UnwindSafe`] trait, for more information see that documentation.
|
||||||
|
///
|
||||||
|
/// [`UnsafeCell`]: ../cell/struct.UnsafeCell.html
|
||||||
|
/// [`UnwindSafe`]: ./trait.UnwindSafe.html
|
||||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||||
#[rustc_on_unimplemented = "the type {Self} may contain interior mutability \
|
#[rustc_on_unimplemented = "the type {Self} may contain interior mutability \
|
||||||
and a reference may not be safely transferrable \
|
and a reference may not be safely transferrable \
|
||||||
@@ -122,14 +130,15 @@ pub auto trait RefUnwindSafe {}
|
|||||||
|
|
||||||
/// A simple wrapper around a type to assert that it is unwind safe.
|
/// A simple wrapper around a type to assert that it is unwind safe.
|
||||||
///
|
///
|
||||||
/// When using `catch_unwind` it may be the case that some of the closed over
|
/// When using [`catch_unwind`] it may be the case that some of the closed over
|
||||||
/// variables are not unwind safe. For example if `&mut T` is captured the
|
/// variables are not unwind safe. For example if `&mut T` is captured the
|
||||||
/// compiler will generate a warning indicating that it is not unwind safe. It
|
/// compiler will generate a warning indicating that it is not unwind safe. It
|
||||||
/// may not be the case, however, that this is actually a problem due to the
|
/// may not be the case, however, that this is actually a problem due to the
|
||||||
/// specific usage of `catch_unwind` if unwind safety is specifically taken into
|
/// specific usage of [`catch_unwind`] if unwind safety is specifically taken into
|
||||||
/// account. This wrapper struct is useful for a quick and lightweight
|
/// account. This wrapper struct is useful for a quick and lightweight
|
||||||
/// annotation that a variable is indeed unwind safe.
|
/// annotation that a variable is indeed unwind safe.
|
||||||
///
|
///
|
||||||
|
/// [`catch_unwind`]: ./fn.catch_unwind.html
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// One way to use `AssertUnwindSafe` is to assert that the entire closure
|
/// One way to use `AssertUnwindSafe` is to assert that the entire closure
|
||||||
@@ -318,18 +327,22 @@ impl<T: fmt::Debug> fmt::Debug for AssertUnwindSafe<T> {
|
|||||||
/// panic and allowing a graceful handling of the error.
|
/// panic and allowing a graceful handling of the error.
|
||||||
///
|
///
|
||||||
/// It is **not** recommended to use this function for a general try/catch
|
/// It is **not** recommended to use this function for a general try/catch
|
||||||
/// mechanism. The `Result` type is more appropriate to use for functions that
|
/// mechanism. The [`Result`] type is more appropriate to use for functions that
|
||||||
/// can fail on a regular basis. Additionally, this function is not guaranteed
|
/// can fail on a regular basis. Additionally, this function is not guaranteed
|
||||||
/// to catch all panics, see the "Notes" section below.
|
/// to catch all panics, see the "Notes" section below.
|
||||||
///
|
///
|
||||||
/// The closure provided is required to adhere to the `UnwindSafe` trait to ensure
|
/// [`Result`]: ../result/enum.Result.html
|
||||||
|
///
|
||||||
|
/// The closure provided is required to adhere to the [`UnwindSafe`] trait to ensure
|
||||||
/// that all captured variables are safe to cross this boundary. The purpose of
|
/// that all captured variables are safe to cross this boundary. The purpose of
|
||||||
/// this bound is to encode the concept of [exception safety][rfc] in the type
|
/// this bound is to encode the concept of [exception safety][rfc] in the type
|
||||||
/// system. Most usage of this function should not need to worry about this
|
/// system. Most usage of this function should not need to worry about this
|
||||||
/// bound as programs are naturally unwind safe without `unsafe` code. If it
|
/// bound as programs are naturally unwind safe without `unsafe` code. If it
|
||||||
/// becomes a problem the associated `AssertUnwindSafe` wrapper type in this
|
/// becomes a problem the [`AssertUnwindSafe`] wrapper struct can be used to quickly
|
||||||
/// module can be used to quickly assert that the usage here is indeed unwind
|
/// assert that the usage here is indeed unwind safe.
|
||||||
/// safe.
|
///
|
||||||
|
/// [`AssertUnwindSafe`]: ./struct.AssertUnwindSafe.html
|
||||||
|
/// [`UnwindSafe`]: ./trait.UnwindSafe.html
|
||||||
///
|
///
|
||||||
/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
|
/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
|
||||||
///
|
///
|
||||||
@@ -364,9 +377,11 @@ pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
|
|||||||
|
|
||||||
/// Triggers a panic without invoking the panic hook.
|
/// Triggers a panic without invoking the panic hook.
|
||||||
///
|
///
|
||||||
/// This is designed to be used in conjunction with `catch_unwind` to, for
|
/// This is designed to be used in conjunction with [`catch_unwind`] to, for
|
||||||
/// example, carry a panic across a layer of C code.
|
/// example, carry a panic across a layer of C code.
|
||||||
///
|
///
|
||||||
|
/// [`catch_unwind`]: ./fn.catch_unwind.html
|
||||||
|
///
|
||||||
/// # Notes
|
/// # Notes
|
||||||
///
|
///
|
||||||
/// Note that panics in Rust are not always implemented via unwinding, but they
|
/// Note that panics in Rust are not always implemented via unwinding, but they
|
||||||
|
|||||||
@@ -76,7 +76,9 @@ static mut HOOK: Hook = Hook::Default;
|
|||||||
/// is invoked. As such, the hook will run with both the aborting and unwinding
|
/// is invoked. As such, the hook will run with both the aborting and unwinding
|
||||||
/// runtimes. The default hook prints a message to standard error and generates
|
/// runtimes. The default hook prints a message to standard error and generates
|
||||||
/// a backtrace if requested, but this behavior can be customized with the
|
/// a backtrace if requested, but this behavior can be customized with the
|
||||||
/// `set_hook` and `take_hook` functions.
|
/// `set_hook` and [`take_hook`] functions.
|
||||||
|
///
|
||||||
|
/// [`take_hook`]: ./fn.take_hook.html
|
||||||
///
|
///
|
||||||
/// The hook is provided with a `PanicInfo` struct which contains information
|
/// The hook is provided with a `PanicInfo` struct which contains information
|
||||||
/// about the origin of the panic, including the payload passed to `panic!` and
|
/// about the origin of the panic, including the payload passed to `panic!` and
|
||||||
@@ -121,6 +123,10 @@ pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) {
|
|||||||
|
|
||||||
/// Unregisters the current panic hook, returning it.
|
/// Unregisters the current panic hook, returning it.
|
||||||
///
|
///
|
||||||
|
/// *See also the function [`set_hook`].*
|
||||||
|
///
|
||||||
|
/// [`set_hook`]: ./fn.set_hook.html
|
||||||
|
///
|
||||||
/// If no custom hook is registered, the default hook will be returned.
|
/// If no custom hook is registered, the default hook will be returned.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
|
|||||||
@@ -24,9 +24,17 @@ use foo::*;
|
|||||||
#[foo::a] //~ ERROR: paths of length greater than one
|
#[foo::a] //~ ERROR: paths of length greater than one
|
||||||
fn _test() {}
|
fn _test() {}
|
||||||
|
|
||||||
|
fn _test_inner() {
|
||||||
|
#![a] // OK
|
||||||
|
}
|
||||||
|
|
||||||
#[a] //~ ERROR: custom attributes cannot be applied to modules
|
#[a] //~ ERROR: custom attributes cannot be applied to modules
|
||||||
mod _test2 {}
|
mod _test2 {}
|
||||||
|
|
||||||
|
mod _test2_inner {
|
||||||
|
#![a] //~ ERROR: custom attributes cannot be applied to modules
|
||||||
|
}
|
||||||
|
|
||||||
#[a = y] //~ ERROR: must only be followed by a delimiter token
|
#[a = y] //~ ERROR: must only be followed by a delimiter token
|
||||||
fn _test3() {}
|
fn _test3() {}
|
||||||
|
|
||||||
@@ -36,19 +44,40 @@ fn _test4() {}
|
|||||||
#[a () = ] //~ ERROR: must only be followed by a delimiter token
|
#[a () = ] //~ ERROR: must only be followed by a delimiter token
|
||||||
fn _test5() {}
|
fn _test5() {}
|
||||||
|
|
||||||
fn main() {
|
fn attrs() {
|
||||||
|
// Statement, item
|
||||||
|
#[a] // OK
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
// Statement, macro
|
||||||
|
#[a] //~ ERROR: custom attributes cannot be applied to statements
|
||||||
|
println!();
|
||||||
|
|
||||||
|
// Statement, semi
|
||||||
|
#[a] //~ ERROR: custom attributes cannot be applied to statements
|
||||||
|
S;
|
||||||
|
|
||||||
|
// Statement, local
|
||||||
#[a] //~ ERROR: custom attributes cannot be applied to statements
|
#[a] //~ ERROR: custom attributes cannot be applied to statements
|
||||||
let _x = 2;
|
let _x = 2;
|
||||||
let _x = #[a] 2;
|
|
||||||
//~^ ERROR: custom attributes cannot be applied to expressions
|
|
||||||
|
|
||||||
let _x: m!(u32) = 3;
|
// Expr
|
||||||
//~^ ERROR: procedural macros cannot be expanded to types
|
let _x = #[a] 2; //~ ERROR: custom attributes cannot be applied to expressions
|
||||||
if let m!(Some(_x)) = Some(3) {
|
|
||||||
//~^ ERROR: procedural macros cannot be expanded to patterns
|
// Opt expr
|
||||||
}
|
let _x = [#[a] 2]; //~ ERROR: custom attributes cannot be applied to expressions
|
||||||
let _x = m!(3);
|
|
||||||
//~^ ERROR: procedural macros cannot be expanded to expressions
|
// Expr macro
|
||||||
m!(let _x = 3;);
|
let _x = #[a] println!(); //~ ERROR: custom attributes cannot be applied to expressions
|
||||||
//~^ ERROR: procedural macros cannot be expanded to statements
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _x: m!(u32) = 3; //~ ERROR: procedural macros cannot be expanded to types
|
||||||
|
if let m!(Some(_x)) = Some(3) {} //~ ERROR: procedural macros cannot be expanded to patterns
|
||||||
|
|
||||||
|
m!(struct S;); //~ ERROR: procedural macros cannot be expanded to statements
|
||||||
|
m!(let _x = 3;); //~ ERROR: procedural macros cannot be expanded to statements
|
||||||
|
|
||||||
|
let _x = m!(3); //~ ERROR: procedural macros cannot be expanded to expressions
|
||||||
|
let _x = [m!(3)]; //~ ERROR: procedural macros cannot be expanded to expressions
|
||||||
}
|
}
|
||||||
|
|||||||
28
src/test/compile-fail/used.rs
Normal file
28
src/test/compile-fail/used.rs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2018 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(used)]
|
||||||
|
|
||||||
|
#[used]
|
||||||
|
static FOO: u32 = 0; // OK
|
||||||
|
|
||||||
|
#[used] //~ ERROR attribute must be applied to a `static` variable
|
||||||
|
fn foo() {}
|
||||||
|
|
||||||
|
#[used] //~ ERROR attribute must be applied to a `static` variable
|
||||||
|
struct Foo {}
|
||||||
|
|
||||||
|
#[used] //~ ERROR attribute must be applied to a `static` variable
|
||||||
|
trait Bar {}
|
||||||
|
|
||||||
|
#[used] //~ ERROR attribute must be applied to a `static` variable
|
||||||
|
impl Bar for Foo {}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
17
src/test/run-pass/vec-const-new.rs
Normal file
17
src/test/run-pass/vec-const-new.rs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2012 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.
|
||||||
|
|
||||||
|
// Test that Vec::new() can be used for constants
|
||||||
|
|
||||||
|
#![feature(const_vec_new)]
|
||||||
|
|
||||||
|
const MY_VEC: Vec<usize> = Vec::new();
|
||||||
|
|
||||||
|
pub fn main() {}
|
||||||
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
// compile-pass
|
// compile-pass
|
||||||
|
|
||||||
|
#![feature(box_syntax)]
|
||||||
|
#![feature(box_patterns)]
|
||||||
#![warn(unused)] // UI tests pass `-A unused` (#43896)
|
#![warn(unused)] // UI tests pass `-A unused` (#43896)
|
||||||
|
|
||||||
struct SoulHistory {
|
struct SoulHistory {
|
||||||
@@ -18,6 +20,13 @@ struct SoulHistory {
|
|||||||
endless_and_singing: bool
|
endless_and_singing: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
enum Large {
|
||||||
|
Suit { case: () }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Tuple(Large, ());
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let i_think_continually = 2;
|
let i_think_continually = 2;
|
||||||
let who_from_the_womb_remembered = SoulHistory {
|
let who_from_the_womb_remembered = SoulHistory {
|
||||||
@@ -31,4 +40,38 @@ fn main() {
|
|||||||
endless_and_singing: true } = who_from_the_womb_remembered {
|
endless_and_singing: true } = who_from_the_womb_remembered {
|
||||||
hours_are_suns = false;
|
hours_are_suns = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let bag = Large::Suit {
|
||||||
|
case: ()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Plain struct
|
||||||
|
match bag {
|
||||||
|
Large::Suit { case } => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Referenced struct
|
||||||
|
match &bag {
|
||||||
|
&Large::Suit { case } => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Boxed struct
|
||||||
|
match box bag {
|
||||||
|
box Large::Suit { case } => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tuple with struct
|
||||||
|
match (bag,) {
|
||||||
|
(Large::Suit { case },) => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Slice with struct
|
||||||
|
match [bag] {
|
||||||
|
[Large::Suit { case }] => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tuple struct with struct
|
||||||
|
match Tuple(bag, ()) {
|
||||||
|
Tuple(Large::Suit { case }, ()) => {}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
warning: unused variable: `i_think_continually`
|
warning: unused variable: `i_think_continually`
|
||||||
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:22:9
|
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:31:9
|
||||||
|
|
|
|
||||||
LL | let i_think_continually = 2;
|
LL | let i_think_continually = 2;
|
||||||
| ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead
|
| ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead
|
||||||
|
|
|
|
||||||
note: lint level defined here
|
note: lint level defined here
|
||||||
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9
|
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:15:9
|
||||||
|
|
|
|
||||||
LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
|
LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
= note: #[warn(unused_variables)] implied by #[warn(unused)]
|
= note: #[warn(unused_variables)] implied by #[warn(unused)]
|
||||||
|
|
||||||
warning: unused variable: `corridors_of_light`
|
warning: unused variable: `corridors_of_light`
|
||||||
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:29:26
|
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:26
|
||||||
|
|
|
|
||||||
LL | if let SoulHistory { corridors_of_light,
|
LL | if let SoulHistory { corridors_of_light,
|
||||||
| ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _`
|
| ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _`
|
||||||
|
|
||||||
warning: variable `hours_are_suns` is assigned to, but never used
|
warning: variable `hours_are_suns` is assigned to, but never used
|
||||||
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:30:26
|
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:39:26
|
||||||
|
|
|
|
||||||
LL | mut hours_are_suns,
|
LL | mut hours_are_suns,
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
@@ -26,15 +26,51 @@ LL | mut hours_are_suns,
|
|||||||
= note: consider using `_hours_are_suns` instead
|
= note: consider using `_hours_are_suns` instead
|
||||||
|
|
||||||
warning: value assigned to `hours_are_suns` is never read
|
warning: value assigned to `hours_are_suns` is never read
|
||||||
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:32:9
|
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:41:9
|
||||||
|
|
|
|
||||||
LL | hours_are_suns = false;
|
LL | hours_are_suns = false;
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: lint level defined here
|
note: lint level defined here
|
||||||
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9
|
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:15:9
|
||||||
|
|
|
|
||||||
LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
|
LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
= note: #[warn(unused_assignments)] implied by #[warn(unused)]
|
= note: #[warn(unused_assignments)] implied by #[warn(unused)]
|
||||||
|
|
||||||
|
warning: unused variable: `case`
|
||||||
|
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:50:23
|
||||||
|
|
|
||||||
|
LL | Large::Suit { case } => {}
|
||||||
|
| ^^^^ help: try ignoring the field: `case: _`
|
||||||
|
|
||||||
|
warning: unused variable: `case`
|
||||||
|
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:55:24
|
||||||
|
|
|
||||||
|
LL | &Large::Suit { case } => {}
|
||||||
|
| ^^^^ help: try ignoring the field: `case: _`
|
||||||
|
|
||||||
|
warning: unused variable: `case`
|
||||||
|
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:60:27
|
||||||
|
|
|
||||||
|
LL | box Large::Suit { case } => {}
|
||||||
|
| ^^^^ help: try ignoring the field: `case: _`
|
||||||
|
|
||||||
|
warning: unused variable: `case`
|
||||||
|
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:65:24
|
||||||
|
|
|
||||||
|
LL | (Large::Suit { case },) => {}
|
||||||
|
| ^^^^ help: try ignoring the field: `case: _`
|
||||||
|
|
||||||
|
warning: unused variable: `case`
|
||||||
|
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:70:24
|
||||||
|
|
|
||||||
|
LL | [Large::Suit { case }] => {}
|
||||||
|
| ^^^^ help: try ignoring the field: `case: _`
|
||||||
|
|
||||||
|
warning: unused variable: `case`
|
||||||
|
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:75:29
|
||||||
|
|
|
||||||
|
LL | Tuple(Large::Suit { case }, ()) => {}
|
||||||
|
| ^^^^ help: try ignoring the field: `case: _`
|
||||||
|
|
||||||
|
|||||||
Submodule src/tools/cargo updated: 0a1add2d86...122fd5be52
Reference in New Issue
Block a user