#![feature(pointer_methods)]
#![feature(inclusive_range_fields)]
#![cfg_attr(stage0, feature(generic_param_attrs))]
+#![feature(rustc_const_unstable)]
#![cfg_attr(not(test), feature(fn_traits, i128))]
#![cfg_attr(test, feature(test))]
impl<T, A: Alloc> RawVec<T, A> {
/// Like `new` but parameterized over the choice of allocator for
/// 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.
- 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"
RawVec {
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,
}
}
/// RawVec with capacity 0. If T has 0 size, then it makes a
/// RawVec with capacity `usize::MAX`. Useful for implementing
/// delayed allocation.
- pub fn new() -> Self {
+ pub const fn new() -> Self {
Self::new_in(Global)
}
/// ```
#[inline]
#[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 {
buf: RawVec::new(),
len: 0,
/// `flatten()` a three-dimensional array the result will be
/// two-dimensional and not one-dimensional. To get a one-dimensional
/// structure, you have to `flatten()` again.
+ ///
+ /// [`flat_map()`]: #method.flat_map
#[inline]
#[unstable(feature = "iterator_flatten", issue = "48213")]
fn flatten(self) -> Flatten<Self>
/// `Pin` pointer.
///
/// This trait is automatically implemented for almost every type.
+///
+/// [`Pin`]: ../mem/struct.Pin.html
#[unstable(feature = "pin", issue = "49150")]
pub unsafe auto trait Unpin {}
/// This is useful for initializing types which lazily allocate, like
/// `Vec::new` does.
// FIXME: rename to dangling() to match NonNull?
- pub fn empty() -> Self {
+ pub const fn empty() -> Self {
unsafe {
- let ptr = mem::align_of::<T>() as *mut T;
- Unique::new_unchecked(ptr)
+ Unique::new_unchecked(mem::align_of::<T>() as *mut T)
}
}
}
Expression,
Statement,
Closure,
+ Static,
Other,
}
hir::ItemEnum(..) => Target::Enum,
hir::ItemConst(..) => Target::Const,
hir::ItemForeignMod(..) => Target::ForeignMod,
+ hir::ItemStatic(..) => Target::Static,
_ => Target::Other,
}
}
}
self.check_repr(item, target);
+ self.check_used(item, target);
}
/// Check if an `#[inline]` is applied to a function or a closure.
}
}
}
+
+ 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> {
use lint;
use util::nodemap::{NodeMap, NodeSet};
+use std::collections::VecDeque;
use std::{fmt, usize};
use std::io::prelude::*;
use std::io;
}
fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
- for pat in &arm.pats {
- // for struct patterns, take note of which fields used shorthand (`x` rather than `x: x`)
+ for mut pat in &arm.pats {
+ // 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
- // out in favor of `HirId`s; however, we need to match the signature of `each_binding`,
- // which uses `NodeIds`.
+ // FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be
+ // phased out in favor of `HirId`s; however, we need to match the signature of
+ // `each_binding`, which uses `NodeIds`.
let mut shorthand_field_ids = NodeSet();
- if let hir::PatKind::Struct(_, ref fields, _) = pat.node {
- for field in fields {
- if field.node.is_shorthand {
- shorthand_field_ids.insert(field.node.pat.id);
+ 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 {
+ if field.node.is_shorthand {
+ 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());
+ }
+ _ => {}
}
}
///
/// 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
/// enforced outside this module with the `EmptyBucket`, `FullBucket`,
/// and `SafeHash` types.
///
/// [`Cow`]: ../borrow/enum.Cow.html
/// [`Borrowed`]: ../borrow/enum.Cow.html#variant.Borrowed
+ /// [`Owned`]: ../borrow/enum.Cow.html#variant.Owned
/// [`str`]: ../primitive.str.html
/// [`String`]: ../string/struct.String.html
///
/// A marker trait which represents "panic safe" types in Rust.
///
/// 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
-/// purpose of this trait is to encode what types are safe to cross a `catch_unwind`
+/// 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`]
/// 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?
///
/// In Rust a function can "return" early if it either panics or calls a
///
/// ## When should `UnwindSafe` be used?
///
-/// 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,
-/// the lack of `unsafe` means it is mostly an advisory. The `AssertUnwindSafe`
-/// wrapper struct in this module can be used to force this trait to be
-/// implemented for any closed over variables passed to the `catch_unwind` function
-/// (more on this below).
+/// 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, the lack of `unsafe` means it is mostly an advisory. The
+/// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be
+/// implemented for any closed over variables passed to `catch_unwind`.
+///
+/// [`AssertUnwindSafe`]: ./struct.AssertUnwindSafe.html
#[stable(feature = "catch_unwind", since = "1.9.0")]
#[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
across an unwind boundary"]
/// A marker trait representing types where a shared reference is considered
/// 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.
///
/// 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")]
#[rustc_on_unimplemented = "the type {Self} may contain interior mutability \
and a reference may not be safely transferrable \
/// 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
/// 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
-/// 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
/// annotation that a variable is indeed unwind safe.
///
+/// [`catch_unwind`]: ./fn.catch_unwind.html
/// # Examples
///
/// One way to use `AssertUnwindSafe` is to assert that the entire closure
/// panic and allowing a graceful handling of the error.
///
/// 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
/// 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
/// 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
/// bound as programs are naturally unwind safe without `unsafe` code. If it
-/// becomes a problem the associated `AssertUnwindSafe` wrapper type in this
-/// module can be used to quickly assert that the usage here is indeed unwind
-/// safe.
+/// becomes a problem the [`AssertUnwindSafe`] wrapper struct can be used to quickly
+/// assert that the usage here is indeed unwind safe.
+///
+/// [`AssertUnwindSafe`]: ./struct.AssertUnwindSafe.html
+/// [`UnwindSafe`]: ./trait.UnwindSafe.html
///
/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
///
/// 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.
///
+/// [`catch_unwind`]: ./fn.catch_unwind.html
+///
/// # Notes
///
/// Note that panics in Rust are not always implemented via unwinding, but they
/// 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
/// 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
/// about the origin of the panic, including the payload passed to `panic!` and
/// 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.
///
/// # Panics
#[foo::a] //~ ERROR: paths of length greater than one
fn _test() {}
+fn _test_inner() {
+ #![a] // OK
+}
+
#[a] //~ ERROR: custom attributes cannot be applied to modules
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
fn _test3() {}
#[a () = ] //~ ERROR: must only be followed by a delimiter token
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
let _x = 2;
- let _x = #[a] 2;
- //~^ ERROR: custom attributes cannot be applied to expressions
-
- 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
- }
- let _x = m!(3);
- //~^ ERROR: procedural macros cannot be expanded to expressions
- m!(let _x = 3;);
- //~^ ERROR: procedural macros cannot be expanded to statements
+
+ // Expr
+ let _x = #[a] 2; //~ ERROR: custom attributes cannot be applied to expressions
+
+ // Opt expr
+ let _x = [#[a] 2]; //~ ERROR: custom attributes cannot be applied to expressions
+
+ // Expr macro
+ let _x = #[a] println!(); //~ ERROR: custom attributes cannot be applied to expressions
+}
+
+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
}
--- /dev/null
+// 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() {}
--- /dev/null
+// 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() {}
// compile-pass
+#![feature(box_syntax)]
+#![feature(box_patterns)]
#![warn(unused)] // UI tests pass `-A unused` (#43896)
struct SoulHistory {
endless_and_singing: bool
}
+#[derive(Clone, Copy)]
+enum Large {
+ Suit { case: () }
+}
+
+struct Tuple(Large, ());
+
fn main() {
let i_think_continually = 2;
let who_from_the_womb_remembered = SoulHistory {
endless_and_singing: true } = who_from_the_womb_remembered {
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 }, ()) => {}
+ };
}
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;
| ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead
|
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)
| ^^^^^^
= note: #[warn(unused_variables)] implied by #[warn(unused)]
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,
| ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _`
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,
| ^^^^^^^^^^^^^^^^^^
= note: consider using `_hours_are_suns` instead
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;
| ^^^^^^^^^^^^^^
|
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)
| ^^^^^^
= 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: _`
+