From 54d6bcbf70112ceb0efa4579ab9f6d5673588889 Mon Sep 17 00:00:00 2001 From: Daiki Mizukami Date: Wed, 11 Apr 2018 18:24:47 +0900 Subject: alloc: Mark `Box::into_unique` with `#[doc(hidden)]` --- src/liballoc/boxed.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 71b53cc88e5..bf7921ea1a2 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -184,6 +184,7 @@ impl Box { #[unstable(feature = "ptr_internals", issue = "0", reason = "use into_raw_non_null instead")] #[inline] + #[doc(hidden)] pub fn into_unique(b: Box) -> Unique { let unique = b.0; mem::forget(b); -- cgit 1.4.1-3-g733a5 From bd8c177d49c95d94f163e9bb3c3397f38ab72640 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Fri, 20 Apr 2018 10:24:53 +0900 Subject: Switch box_free to take the destructured contents of Box As of now, Box only contains a Unique pointer, so this is the sole argument to box_free. Consequently, we remove the code supporting the previous box_free signature. We however keep the old definition for bootstrapping purpose. --- src/liballoc/alloc.rs | 14 ++++++-- src/liballoc/arc.rs | 5 +-- src/liballoc/rc.rs | 5 +-- src/librustc_mir/util/elaborate_drops.rs | 61 +++++++------------------------- 4 files changed, 29 insertions(+), 56 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 68a617e0ffe..ed860678765 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -16,7 +16,7 @@ issue = "32838")] use core::intrinsics::{min_align_of_val, size_of_val}; -use core::ptr::NonNull; +use core::ptr::{NonNull, Unique}; use core::usize; #[doc(inline)] @@ -170,9 +170,17 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { } } -#[cfg_attr(not(test), lang = "box_free")] +#[cfg(stage0)] +#[lang = "box_free"] +#[inline] +unsafe fn old_box_free(ptr: *mut T) { + box_free(Unique::new_unchecked(ptr)) +} + +#[cfg_attr(not(any(test, stage0)), lang = "box_free")] #[inline] -pub(crate) unsafe fn box_free(ptr: *mut T) { +pub(crate) unsafe fn box_free(ptr: Unique) { + let ptr = ptr.as_ptr(); let size = size_of_val(&*ptr); let align = min_align_of_val(&*ptr); // We do not allocate for Box when T is ZST, so deallocation is also not necessary. diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 225b055d8ee..a1ec5cd2208 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -566,7 +566,8 @@ impl Arc { fn from_box(v: Box) -> Arc { unsafe { - let bptr = Box::into_raw(v); + let box_unique = Box::into_unique(v); + let bptr = box_unique.as_ptr(); let value_size = size_of_val(&*bptr); let ptr = Self::allocate_for_ptr(bptr); @@ -578,7 +579,7 @@ impl Arc { value_size); // Free the allocation without dropping its contents - box_free(bptr); + box_free(box_unique); Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index de0422d82bb..c495d300805 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -681,7 +681,8 @@ impl Rc { fn from_box(v: Box) -> Rc { unsafe { - let bptr = Box::into_raw(v); + let box_unique = Box::into_unique(v); + let bptr = box_unique.as_ptr(); let value_size = size_of_val(&*bptr); let ptr = Self::allocate_for_ptr(bptr); @@ -693,7 +694,7 @@ impl Rc { value_size); // Free the allocation without dropping its contents - box_free(bptr); + box_free(box_unique); Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index cc91bbf9061..02020c3b7a4 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -879,56 +879,19 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let tcx = self.tcx(); let unit_temp = Place::Local(self.new_temp(tcx.mk_nil())); let free_func = tcx.require_lang_item(lang_items::BoxFreeFnLangItem); - let free_sig = tcx.fn_sig(free_func).skip_binder().clone(); - let free_inputs = free_sig.inputs(); - // If the box_free function takes a *mut T, transform the Box into - // such a pointer before calling box_free. Otherwise, pass it all - // the fields in the Box as individual arguments. - let (stmts, args) = if free_inputs.len() == 1 && free_inputs[0].is_mutable_pointer() { - let ty = substs.type_at(0); - let ref_ty = tcx.mk_ref(tcx.types.re_erased, ty::TypeAndMut { - ty: ty, - mutbl: hir::Mutability::MutMutable - }); - let ptr_ty = tcx.mk_mut_ptr(ty); - let ref_tmp = Place::Local(self.new_temp(ref_ty)); - let ptr_tmp = Place::Local(self.new_temp(ptr_ty)); - let stmts = vec![ - self.assign(&ref_tmp, Rvalue::Ref( - tcx.types.re_erased, - BorrowKind::Mut { allow_two_phase_borrow: false }, - self.place.clone().deref() - )), - self.assign(&ptr_tmp, Rvalue::Cast( - CastKind::Misc, - Operand::Move(ref_tmp), - ptr_ty, - )), - ]; - (stmts, vec![Operand::Move(ptr_tmp)]) - } else { - let args = adt.variants[0].fields.iter().enumerate().map(|(i, f)| { - let field = Field::new(i); - let field_ty = f.ty(self.tcx(), substs); - Operand::Move(self.place.clone().field(field, field_ty)) - }).collect(); - (vec![], args) - }; + let args = adt.variants[0].fields.iter().enumerate().map(|(i, f)| { + let field = Field::new(i); + let field_ty = f.ty(self.tcx(), substs); + Operand::Move(self.place.clone().field(field, field_ty)) + }).collect(); - let free_block = BasicBlockData { - statements: stmts, - terminator: Some(Terminator { - kind: TerminatorKind::Call { - func: Operand::function_handle(tcx, free_func, substs, self.source_info.span), - args: args, - destination: Some((unit_temp, target)), - cleanup: None - }, // FIXME(#43234) - source_info: self.source_info, - }), - is_cleanup: unwind.is_cleanup() - }; - let free_block = self.elaborator.patch().new_block(free_block); + let call = TerminatorKind::Call { + func: Operand::function_handle(tcx, free_func, substs, self.source_info.span), + args: args, + destination: Some((unit_temp, target)), + cleanup: None + }; // FIXME(#43234) + let free_block = self.new_block(unwind, call); let block_start = Location { block: free_block, statement_index: 0 }; self.elaborator.clear_drop_flag(block_start, self.path, DropFlagMode::Shallow); -- cgit 1.4.1-3-g733a5 From 256096da9ee680366b839f912e8d3ecccc0da033 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Wed, 25 Apr 2018 16:33:02 -0500 Subject: Make Vec::new const --- src/liballoc/raw_vec.rs | 16 ++++++++++++++++ src/liballoc/vec.rs | 2 +- src/libcore/ptr.rs | 5 ++--- src/test/run-pass/vec-const-new.rs | 15 +++++++++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 src/test/run-pass/vec-const-new.rs (limited to 'src/liballoc') diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 7ef0a27fc72..dc8ad9ee061 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -68,6 +68,16 @@ impl RawVec { } } + /// Like `empty` but parametrized over the choice of allocator for the returned `RawVec`. + pub const fn empty_in(a: A) -> Self { + // Unique::empty() doubles as "unallocated" and "zero-sized allocation" + RawVec { + ptr: Unique::empty(), + cap: 0, + a, + } + } + /// Like `with_capacity` but parameterized over the choice of /// allocator for the returned RawVec. #[inline] @@ -124,6 +134,12 @@ impl RawVec { Self::new_in(Global) } + /// Create a `RawVec` with capcity 0 (on the system heap), regardless of `T`, without + /// allocating. + pub fn empty() -> Self { + Self::empty_in(Global) + } + /// Creates a RawVec (on the system heap) with exactly the /// capacity and alignment requirements for a `[T; cap]`. This is /// equivalent to calling RawVec::new when `cap` is 0 or T is diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index b184404c15b..757606607bb 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -324,7 +324,7 @@ impl Vec { #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> Vec { Vec { - buf: RawVec::new(), + buf: RawVec::empty(), len: 0, } } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 74bb264cc67..b612a278a34 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2551,10 +2551,9 @@ impl Unique { /// 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::() as *mut T; - Unique::new_unchecked(ptr) + Unique::new_unchecked(mem::align_of::() as *mut T) } } } diff --git a/src/test/run-pass/vec-const-new.rs b/src/test/run-pass/vec-const-new.rs new file mode 100644 index 00000000000..02d8cfdcf98 --- /dev/null +++ b/src/test/run-pass/vec-const-new.rs @@ -0,0 +1,15 @@ +// 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 or the MIT license +// , 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 + +const MY_VEC: Vec = Vec::new(); + +pub fn main() {} -- cgit 1.4.1-3-g733a5 From a2105b8e21a71f513e6840ec0571cad5c1a36012 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Wed, 25 Apr 2018 16:42:57 -0500 Subject: make RawVec::empty const --- src/liballoc/raw_vec.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index dc8ad9ee061..fe18979fb51 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -54,6 +54,7 @@ pub struct RawVec { } impl RawVec { + // FIXME: this should be made `const` when `if` statements are allowed /// Like `new` but parameterized over the choice of allocator for /// the returned RawVec. pub fn new_in(a: A) -> Self { @@ -68,6 +69,7 @@ impl RawVec { } } + // FIXME: this should removed when `new_in` can be made `const` /// Like `empty` but parametrized over the choice of allocator for the returned `RawVec`. pub const fn empty_in(a: A) -> Self { // Unique::empty() doubles as "unallocated" and "zero-sized allocation" @@ -134,9 +136,10 @@ impl RawVec { Self::new_in(Global) } + // FIXME: this should removed when `new` can be made `const` /// Create a `RawVec` with capcity 0 (on the system heap), regardless of `T`, without /// allocating. - pub fn empty() -> Self { + pub const fn empty() -> Self { Self::empty_in(Global) } -- cgit 1.4.1-3-g733a5 From 20ef0e001a1620436073d01f43a4a462d1967902 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 26 Apr 2018 12:46:28 -0500 Subject: make Vec::new const :P --- src/liballoc/vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 757606607bb..1d95f76fd77 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -322,7 +322,7 @@ impl Vec { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> Vec { + pub const fn new() -> Vec { Vec { buf: RawVec::empty(), len: 0, -- cgit 1.4.1-3-g733a5 From c122b3a42c5dd57682be353cb9433241f67ab9cb Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 26 Apr 2018 22:38:39 -0500 Subject: not insta-stable --- src/liballoc/lib.rs | 1 + src/liballoc/vec.rs | 1 + 2 files changed, 2 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 6399be98cd5..c4950786265 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -123,6 +123,7 @@ #![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))] diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 1d95f76fd77..415d75664ff 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -322,6 +322,7 @@ impl Vec { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_vec_new")] pub const fn new() -> Vec { Vec { buf: RawVec::empty(), -- cgit 1.4.1-3-g733a5 From 3dbdccc6a9c1ead58325d415381b25c676386c34 Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Sat, 10 Mar 2018 16:23:28 -0800 Subject: stabilize `#[must_use]` for functions and must-use operators This is in the matter of RFC 1940 and tracking issue #43302. --- .../src/language-features/fn-must-use.md | 30 ---- src/liballoc/lib.rs | 2 +- src/liballoc/tests/slice.rs | 1 + src/libcore/lib.rs | 2 +- src/librustc_lint/unused.rs | 104 +++++++------- src/libstd/ffi/c_str.rs | 2 + src/libstd/sync/mpsc/select.rs | 2 + src/libsyntax/feature_gate.rs | 22 +-- .../ui/feature-gate-fn_must_use-cap-lints-allow.rs | 22 --- ...feature-gate-fn_must_use-cap-lints-allow.stderr | 8 -- src/test/ui/feature-gate-fn_must_use.rs | 31 ----- src/test/ui/feature-gate-fn_must_use.stderr | 24 ---- .../issue-43106-gating-of-builtin-attrs.rs | 1 - .../issue-43106-gating-of-builtin-attrs.stderr | 154 ++++++++++----------- src/test/ui/fn_must_use.rs | 78 +++++++++++ src/test/ui/fn_must_use.stderr | 48 +++++++ src/test/ui/lint/must-use-ops.rs | 1 - src/test/ui/lint/must-use-ops.stderr | 44 +++--- .../rfc_1940-must_use_on_functions/fn_must_use.rs | 79 ----------- .../fn_must_use.stderr | 48 ------- src/test/ui/span/gated-features-attr-spans.rs | 23 --- src/test/ui/span/gated-features-attr-spans.stderr | 18 +-- 22 files changed, 284 insertions(+), 460 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/fn-must-use.md delete mode 100644 src/test/ui/feature-gate-fn_must_use-cap-lints-allow.rs delete mode 100644 src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr delete mode 100644 src/test/ui/feature-gate-fn_must_use.rs delete mode 100644 src/test/ui/feature-gate-fn_must_use.stderr create mode 100644 src/test/ui/fn_must_use.rs create mode 100644 src/test/ui/fn_must_use.stderr delete mode 100644 src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs delete mode 100644 src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr (limited to 'src/liballoc') diff --git a/src/doc/unstable-book/src/language-features/fn-must-use.md b/src/doc/unstable-book/src/language-features/fn-must-use.md deleted file mode 100644 index 71b6cd663a0..00000000000 --- a/src/doc/unstable-book/src/language-features/fn-must-use.md +++ /dev/null @@ -1,30 +0,0 @@ -# `fn_must_use` - -The tracking issue for this feature is [#43302]. - -[#43302]: https://github.com/rust-lang/rust/issues/43302 - ------------------------- - -The `fn_must_use` feature allows functions and methods to be annotated with -`#[must_use]`, indicating that the `unused_must_use` lint should require their -return values to be used (similarly to how types annotated with `must_use`, -most notably `Result`, are linted if not used). - -## Examples - -```rust -#![feature(fn_must_use)] - -#[must_use] -fn double(x: i32) -> i32 { - 2 * x -} - -fn main() { - double(4); // warning: unused return value of `double` which must be used - - let _ = double(4); // (no warning) -} - -``` diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 021395d0c82..fa74352c23c 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -96,7 +96,7 @@ #![feature(dropck_eyepatch)] #![feature(exact_size_is_empty)] #![feature(fmt_internals)] -#![feature(fn_must_use)] +#![cfg_attr(stage0, feature(fn_must_use))] #![feature(from_ref)] #![feature(fundamental)] #![feature(lang_items)] diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 99d9c51efc7..6fd0b33f02a 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1282,6 +1282,7 @@ fn test_box_slice_clone() { } #[test] +#[allow(unused_must_use)] // here, we care about the side effects of `.clone()` #[cfg_attr(target_os = "emscripten", ignore)] fn test_box_slice_clone_panics() { use std::sync::Arc; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 0e21a3327fd..f4ed24cc3a3 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -76,7 +76,6 @@ #![feature(doc_cfg)] #![feature(doc_spotlight)] #![feature(extern_types)] -#![feature(fn_must_use)] #![feature(fundamental)] #![feature(intrinsics)] #![feature(iterator_flatten)] @@ -114,6 +113,7 @@ #![cfg_attr(stage0, feature(target_feature))] #![cfg_attr(stage0, feature(cfg_target_feature))] +#![cfg_attr(stage0, feature(fn_must_use))] #[prelude_import] #[allow(unused)] diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index c32e9cdce0e..9e1b75ba336 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -73,59 +73,59 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { let mut fn_warned = false; let mut op_warned = false; - if cx.tcx.features().fn_must_use { - let maybe_def = match expr.node { - hir::ExprCall(ref callee, _) => { - match callee.node { - hir::ExprPath(ref qpath) => { - let def = cx.tables.qpath_def(qpath, callee.hir_id); - if let Def::Fn(_) = def { - Some(def) - } else { // `Def::Local` if it was a closure, for which we - None // do not currently support must-use linting - } - }, - _ => None - } - }, - hir::ExprMethodCall(..) => { - cx.tables.type_dependent_defs().get(expr.hir_id).cloned() - }, - _ => None - }; - if let Some(def) = maybe_def { - let def_id = def.def_id(); - fn_warned = check_must_use(cx, def_id, s.span, "return value of "); - } - let must_use_op = match expr.node { - // Hardcoding operators here seemed more expedient than the - // refactoring that would be needed to look up the `#[must_use]` - // attribute which does exist on the comparison trait methods - hir::ExprBinary(bin_op, ..) => { - match bin_op.node { - hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => { - Some("comparison") - }, - hir::BiAdd | hir::BiSub | hir::BiDiv | hir::BiMul | hir::BiRem => { - Some("arithmetic operation") - }, - hir::BiAnd | hir::BiOr => { - Some("logical operation") - }, - hir::BiBitXor | hir::BiBitAnd | hir::BiBitOr | hir::BiShl | hir::BiShr => { - Some("bitwise operation") - }, - } - }, - hir::ExprUnary(..) => Some("unary operation"), - _ => None - }; - if let Some(must_use_op) = must_use_op { - cx.span_lint(UNUSED_MUST_USE, expr.span, - &format!("unused {} which must be used", must_use_op)); - op_warned = true; - } + let maybe_def = match expr.node { + hir::ExprCall(ref callee, _) => { + match callee.node { + hir::ExprPath(ref qpath) => { + let def = cx.tables.qpath_def(qpath, callee.hir_id); + if let Def::Fn(_) = def { + Some(def) + } else { // `Def::Local` if it was a closure, for which we + None // do not currently support must-use linting + } + }, + _ => None + } + }, + hir::ExprMethodCall(..) => { + cx.tables.type_dependent_defs().get(expr.hir_id).cloned() + }, + _ => None + }; + if let Some(def) = maybe_def { + let def_id = def.def_id(); + fn_warned = check_must_use(cx, def_id, s.span, "return value of "); } + let must_use_op = match expr.node { + // Hardcoding operators here seemed more expedient than the + // refactoring that would be needed to look up the `#[must_use]` + // attribute which does exist on the comparison trait methods + hir::ExprBinary(bin_op, ..) => { + match bin_op.node { + hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => { + Some("comparison") + }, + hir::BiAdd | hir::BiSub | hir::BiDiv | hir::BiMul | hir::BiRem => { + Some("arithmetic operation") + }, + hir::BiAnd | hir::BiOr => { + Some("logical operation") + }, + hir::BiBitXor | hir::BiBitAnd | hir::BiBitOr | hir::BiShl | hir::BiShr => { + Some("bitwise operation") + }, + } + }, + hir::ExprUnary(..) => Some("unary operation"), + _ => None + }; + + if let Some(must_use_op) = must_use_op { + cx.span_lint(UNUSED_MUST_USE, expr.span, + &format!("unused {} which must be used", must_use_op)); + op_warned = true; + } + if !(ty_warned || fn_warned || op_warned) { cx.span_lint(UNUSED_RESULTS, s.span, "unused result"); } diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index c88c2bc9137..d4937c00012 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -988,6 +988,7 @@ impl CStr { /// behavior when `ptr` is used inside the `unsafe` block: /// /// ```no_run + /// # #![allow(unused_must_use)] /// use std::ffi::{CString}; /// /// let ptr = CString::new("Hello").unwrap().as_ptr(); @@ -1003,6 +1004,7 @@ impl CStr { /// To fix the problem, bind the `CString` to a local variable: /// /// ```no_run + /// # #![allow(unused_must_use)] /// use std::ffi::{CString}; /// /// let hello = CString::new("Hello").unwrap(); diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs index a9f3cea243f..9310dad9172 100644 --- a/src/libstd/sync/mpsc/select.rs +++ b/src/libstd/sync/mpsc/select.rs @@ -518,6 +518,7 @@ mod tests { } } + #[allow(unused_must_use)] #[test] fn cloning() { let (tx1, rx1) = channel::(); @@ -540,6 +541,7 @@ mod tests { tx3.send(()).unwrap(); } + #[allow(unused_must_use)] #[test] fn cloning2() { let (tx1, rx1) = channel::(); diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index a4a83712a08..f16b1ba440a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -369,9 +369,6 @@ declare_features! ( // #[doc(include="some-file")] (active, external_doc, "1.22.0", Some(44732), None), - // allow `#[must_use]` on functions and comparison operators (RFC 1940) - (active, fn_must_use, "1.21.0", Some(43302), None), - // Future-proofing enums/structs with #[non_exhaustive] attribute (RFC 2008) (active, non_exhaustive, "1.22.0", Some(44109), None), @@ -591,6 +588,8 @@ declare_features! ( (accepted, target_feature, "1.27.0", None, None), // Trait object syntax with `dyn` prefix (accepted, dyn_trait, "1.27.0", Some(44662), None), + // allow `#[must_use]` on functions; and, must-use operators (RFC 1940) + (accepted, fn_must_use, "1.27.0", Some(43302), None), ); // If you change this, please modify src/doc/unstable-book as well. You must @@ -1545,11 +1544,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { function may change over time, for now \ a top-level `fn main()` is required"); } - if let Some(attr) = attr::find_by_name(&i.attrs[..], "must_use") { - gate_feature_post!(&self, fn_must_use, attr.span, - "`#[must_use]` on functions is experimental", - GateStrength::Soft); - } } ast::ItemKind::Struct(..) => { @@ -1581,7 +1575,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { "trait aliases are not yet fully implemented"); } - ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, ref impl_items) => { + ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => { if polarity == ast::ImplPolarity::Negative { gate_feature_post!(&self, optin_builtin_traits, i.span, @@ -1594,16 +1588,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { i.span, "specialization is unstable"); } - - for impl_item in impl_items { - if let ast::ImplItemKind::Method(..) = impl_item.node { - if let Some(attr) = attr::find_by_name(&impl_item.attrs[..], "must_use") { - gate_feature_post!(&self, fn_must_use, attr.span, - "`#[must_use]` on methods is experimental", - GateStrength::Soft); - } - } - } } ast::ItemKind::Trait(ast::IsAuto::Yes, ..) => { diff --git a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.rs b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.rs deleted file mode 100644 index 1c04199c05f..00000000000 --- a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2017 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags: --cap-lints allow - -// This tests that the fn_must_use feature-gate warning respects the lint -// cap. (See discussion in Issue #44213.) - -#![feature(rustc_attrs)] - -#[must_use] // (no feature-gate warning because of the lint cap!) -fn need_to_use_it() -> bool { true } - -#[rustc_error] -fn main() {} //~ ERROR compilation successful diff --git a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr deleted file mode 100644 index a2c1dedff38..00000000000 --- a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: compilation successful - --> $DIR/feature-gate-fn_must_use-cap-lints-allow.rs:22:1 - | -LL | fn main() {} //~ ERROR compilation successful - | ^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/feature-gate-fn_must_use.rs b/src/test/ui/feature-gate-fn_must_use.rs deleted file mode 100644 index 72fdcc76cf4..00000000000 --- a/src/test/ui/feature-gate-fn_must_use.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(rustc_attrs)] - -struct MyStruct; - -impl MyStruct { - #[must_use] //~ WARN `#[must_use]` on methods is experimental - fn need_to_use_method() -> bool { true } -} - -#[must_use] //~ WARN `#[must_use]` on functions is experimental -fn need_to_use_it() -> bool { true } - - -// Feature gates are tidy-required to have a specially named (or -// comment-annotated) compile-fail test (which MUST fail), but for -// backwards-compatibility reasons, we want `#[must_use]` on functions to be -// compilable even if the `fn_must_use` feature is absent, thus necessitating -// the usage of `#[rustc_error]` here, pragmatically if awkwardly solving this -// dilemma until a superior solution can be devised. -#[rustc_error] -fn main() {} //~ ERROR compilation successful diff --git a/src/test/ui/feature-gate-fn_must_use.stderr b/src/test/ui/feature-gate-fn_must_use.stderr deleted file mode 100644 index 431c57abd26..00000000000 --- a/src/test/ui/feature-gate-fn_must_use.stderr +++ /dev/null @@ -1,24 +0,0 @@ -warning: `#[must_use]` on methods is experimental (see issue #43302) - --> $DIR/feature-gate-fn_must_use.rs:16:5 - | -LL | #[must_use] //~ WARN `#[must_use]` on methods is experimental - | ^^^^^^^^^^^ - | - = help: add #![feature(fn_must_use)] to the crate attributes to enable - -warning: `#[must_use]` on functions is experimental (see issue #43302) - --> $DIR/feature-gate-fn_must_use.rs:20:1 - | -LL | #[must_use] //~ WARN `#[must_use]` on functions is experimental - | ^^^^^^^^^^^ - | - = help: add #![feature(fn_must_use)] to the crate attributes to enable - -error: compilation successful - --> $DIR/feature-gate-fn_must_use.rs:31:1 - | -LL | fn main() {} //~ ERROR compilation successful - | ^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs index 21950402c8c..7b0c81dbab6 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs @@ -661,7 +661,6 @@ mod must_use { mod inner { #![must_use="1400"] } #[must_use = "1400"] fn f() { } - //~^ WARN `#[must_use]` on functions is experimental #[must_use = "1400"] struct S; diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 0beed627987..76ab50c9089 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -12,14 +12,6 @@ LL | mod inner { #![macro_escape] } | = help: consider an outer attribute, #[macro_use] mod ... -warning: `#[must_use]` on functions is experimental (see issue #43302) - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:5 - | -LL | #[must_use = "1400"] fn f() { } - | ^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(fn_must_use)] to the crate attributes to enable - warning: unknown lint: `x5400` --> $DIR/issue-43106-gating-of-builtin-attrs.rs:49:33 | @@ -799,433 +791,433 @@ LL | #[no_std = "2600"] | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:691:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:691:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:695:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:695:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:699:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:699:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:703:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:703:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:707:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:707:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:17 | LL | mod inner { #![crate_type="0800"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:17 | LL | mod inner { #![crate_type="0800"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:720:5 | LL | #[crate_type = "0800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:720:5 | LL | #[crate_type = "0800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:5 | LL | #[crate_type = "0800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:5 | LL | #[crate_type = "0800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:728:5 | LL | #[crate_type = "0800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:728:5 | LL | #[crate_type = "0800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:5 | LL | #[crate_type = "0800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:5 | LL | #[crate_type = "0800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:1 | LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:1 | LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:741:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:741:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:745:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:745:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:749:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:749:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:753:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:753:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:757:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:757:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:768:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:767:17 | LL | mod inner { #![no_main="0400"] } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:768:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:767:17 | LL | mod inner { #![no_main="0400"] } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:772:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:771:5 | LL | #[no_main = "0400"] fn f() { } | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:772:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:771:5 | LL | #[no_main = "0400"] fn f() { } | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:775:5 | LL | #[no_main = "0400"] struct S; | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:775:5 | LL | #[no_main = "0400"] struct S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:779:5 | LL | #[no_main = "0400"] type T = S; | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:779:5 | LL | #[no_main = "0400"] type T = S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:783:5 | LL | #[no_main = "0400"] impl S { } | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:783:5 | LL | #[no_main = "0400"] impl S { } | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:763:1 | LL | #[no_main = "0400"] | ^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:763:1 | LL | #[no_main = "0400"] | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:805:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:805:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:809:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:809:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:813:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:813:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:817:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:817:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:821:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:821:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:830:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:830:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:835:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:834:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:835:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:834:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:839:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:838:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:839:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:838:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:842:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:842:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:846:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:846:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1309,7 +1301,7 @@ LL | #![proc_macro_derive = "2500"] //~ WARN unused attribute | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: compilation successful - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:858:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:857:1 | LL | / fn main() { //~ ERROR compilation successful LL | | println!("Hello World"); diff --git a/src/test/ui/fn_must_use.rs b/src/test/ui/fn_must_use.rs new file mode 100644 index 00000000000..def23046db2 --- /dev/null +++ b/src/test/ui/fn_must_use.rs @@ -0,0 +1,78 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-pass + +#![warn(unused_must_use)] + +#[derive(PartialEq, Eq)] +struct MyStruct { + n: usize, +} + +impl MyStruct { + #[must_use] + fn need_to_use_this_method_value(&self) -> usize { + self.n + } +} + +trait EvenNature { + #[must_use = "no side effects"] + fn is_even(&self) -> bool; +} + +impl EvenNature for MyStruct { + fn is_even(&self) -> bool { + self.n % 2 == 0 + } +} + +trait Replaceable { + fn replace(&mut self, substitute: usize) -> usize; +} + +impl Replaceable for MyStruct { + // ↓ N.b.: `#[must_use]` attribute on a particular trait implementation + // method won't work; the attribute should be on the method signature in + // the trait's definition. + #[must_use] + fn replace(&mut self, substitute: usize) -> usize { + let previously = self.n; + self.n = substitute; + previously + } +} + +#[must_use = "it's important"] +fn need_to_use_this_value() -> bool { + false +} + +fn main() { + need_to_use_this_value(); //~ WARN unused return value + + let mut m = MyStruct { n: 2 }; + let n = MyStruct { n: 3 }; + + m.need_to_use_this_method_value(); //~ WARN unused return value + m.is_even(); // trait method! + //~^ WARN unused return value + + m.replace(3); // won't warn (annotation needs to be in trait definition) + + // comparison methods are `must_use` + 2.eq(&3); //~ WARN unused return value + m.eq(&n); //~ WARN unused return value + + // lint includes comparison operators + 2 == 3; //~ WARN unused comparison + m == n; //~ WARN unused comparison +} diff --git a/src/test/ui/fn_must_use.stderr b/src/test/ui/fn_must_use.stderr new file mode 100644 index 00000000000..5026dac0a94 --- /dev/null +++ b/src/test/ui/fn_must_use.stderr @@ -0,0 +1,48 @@ +warning: unused return value of `need_to_use_this_value` which must be used: it's important + --> $DIR/fn_must_use.rs:60:5 + | +LL | need_to_use_this_value(); //~ WARN unused return value + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/fn_must_use.rs:13:9 + | +LL | #![warn(unused_must_use)] + | ^^^^^^^^^^^^^^^ + +warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used + --> $DIR/fn_must_use.rs:65:5 + | +LL | m.need_to_use_this_method_value(); //~ WARN unused return value + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: unused return value of `EvenNature::is_even` which must be used: no side effects + --> $DIR/fn_must_use.rs:66:5 + | +LL | m.is_even(); // trait method! + | ^^^^^^^^^^^^ + +warning: unused return value of `std::cmp::PartialEq::eq` which must be used + --> $DIR/fn_must_use.rs:72:5 + | +LL | 2.eq(&3); //~ WARN unused return value + | ^^^^^^^^^ + +warning: unused return value of `std::cmp::PartialEq::eq` which must be used + --> $DIR/fn_must_use.rs:73:5 + | +LL | m.eq(&n); //~ WARN unused return value + | ^^^^^^^^^ + +warning: unused comparison which must be used + --> $DIR/fn_must_use.rs:76:5 + | +LL | 2 == 3; //~ WARN unused comparison + | ^^^^^^ + +warning: unused comparison which must be used + --> $DIR/fn_must_use.rs:77:5 + | +LL | m == n; //~ WARN unused comparison + | ^^^^^^ + diff --git a/src/test/ui/lint/must-use-ops.rs b/src/test/ui/lint/must-use-ops.rs index 4ed82ab3b40..c0575f817c8 100644 --- a/src/test/ui/lint/must-use-ops.rs +++ b/src/test/ui/lint/must-use-ops.rs @@ -12,7 +12,6 @@ // compile-pass -#![feature(fn_must_use)] #![warn(unused_must_use)] fn main() { diff --git a/src/test/ui/lint/must-use-ops.stderr b/src/test/ui/lint/must-use-ops.stderr index f444ef09075..5703536ef48 100644 --- a/src/test/ui/lint/must-use-ops.stderr +++ b/src/test/ui/lint/must-use-ops.stderr @@ -1,131 +1,131 @@ warning: unused comparison which must be used - --> $DIR/must-use-ops.rs:23:5 + --> $DIR/must-use-ops.rs:22:5 | LL | val == 1; | ^^^^^^^^ | note: lint level defined here - --> $DIR/must-use-ops.rs:16:9 + --> $DIR/must-use-ops.rs:15:9 | LL | #![warn(unused_must_use)] | ^^^^^^^^^^^^^^^ warning: unused comparison which must be used - --> $DIR/must-use-ops.rs:24:5 + --> $DIR/must-use-ops.rs:23:5 | LL | val < 1; | ^^^^^^^ warning: unused comparison which must be used - --> $DIR/must-use-ops.rs:25:5 + --> $DIR/must-use-ops.rs:24:5 | LL | val <= 1; | ^^^^^^^^ warning: unused comparison which must be used - --> $DIR/must-use-ops.rs:26:5 + --> $DIR/must-use-ops.rs:25:5 | LL | val != 1; | ^^^^^^^^ warning: unused comparison which must be used - --> $DIR/must-use-ops.rs:27:5 + --> $DIR/must-use-ops.rs:26:5 | LL | val >= 1; | ^^^^^^^^ warning: unused comparison which must be used - --> $DIR/must-use-ops.rs:28:5 + --> $DIR/must-use-ops.rs:27:5 | LL | val > 1; | ^^^^^^^ warning: unused arithmetic operation which must be used - --> $DIR/must-use-ops.rs:31:5 + --> $DIR/must-use-ops.rs:30:5 | LL | val + 2; | ^^^^^^^ warning: unused arithmetic operation which must be used - --> $DIR/must-use-ops.rs:32:5 + --> $DIR/must-use-ops.rs:31:5 | LL | val - 2; | ^^^^^^^ warning: unused arithmetic operation which must be used - --> $DIR/must-use-ops.rs:33:5 + --> $DIR/must-use-ops.rs:32:5 | LL | val / 2; | ^^^^^^^ warning: unused arithmetic operation which must be used - --> $DIR/must-use-ops.rs:34:5 + --> $DIR/must-use-ops.rs:33:5 | LL | val * 2; | ^^^^^^^ warning: unused arithmetic operation which must be used - --> $DIR/must-use-ops.rs:35:5 + --> $DIR/must-use-ops.rs:34:5 | LL | val % 2; | ^^^^^^^ warning: unused logical operation which must be used - --> $DIR/must-use-ops.rs:38:5 + --> $DIR/must-use-ops.rs:37:5 | LL | true && true; | ^^^^^^^^^^^^ warning: unused logical operation which must be used - --> $DIR/must-use-ops.rs:39:5 + --> $DIR/must-use-ops.rs:38:5 | LL | false || true; | ^^^^^^^^^^^^^ warning: unused bitwise operation which must be used - --> $DIR/must-use-ops.rs:42:5 + --> $DIR/must-use-ops.rs:41:5 | LL | 5 ^ val; | ^^^^^^^ warning: unused bitwise operation which must be used - --> $DIR/must-use-ops.rs:43:5 + --> $DIR/must-use-ops.rs:42:5 | LL | 5 & val; | ^^^^^^^ warning: unused bitwise operation which must be used - --> $DIR/must-use-ops.rs:44:5 + --> $DIR/must-use-ops.rs:43:5 | LL | 5 | val; | ^^^^^^^ warning: unused bitwise operation which must be used - --> $DIR/must-use-ops.rs:45:5 + --> $DIR/must-use-ops.rs:44:5 | LL | 5 << val; | ^^^^^^^^ warning: unused bitwise operation which must be used - --> $DIR/must-use-ops.rs:46:5 + --> $DIR/must-use-ops.rs:45:5 | LL | 5 >> val; | ^^^^^^^^ warning: unused unary operation which must be used - --> $DIR/must-use-ops.rs:49:5 + --> $DIR/must-use-ops.rs:48:5 | LL | !val; | ^^^^ warning: unused unary operation which must be used - --> $DIR/must-use-ops.rs:50:5 + --> $DIR/must-use-ops.rs:49:5 | LL | -val; | ^^^^ warning: unused unary operation which must be used - --> $DIR/must-use-ops.rs:51:5 + --> $DIR/must-use-ops.rs:50:5 | LL | *val_pointer; | ^^^^^^^^^^^^ diff --git a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs b/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs deleted file mode 100644 index d20ebf0b740..00000000000 --- a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2017 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-pass - -#![feature(fn_must_use)] -#![warn(unused_must_use)] - -#[derive(PartialEq, Eq)] -struct MyStruct { - n: usize, -} - -impl MyStruct { - #[must_use] - fn need_to_use_this_method_value(&self) -> usize { - self.n - } -} - -trait EvenNature { - #[must_use = "no side effects"] - fn is_even(&self) -> bool; -} - -impl EvenNature for MyStruct { - fn is_even(&self) -> bool { - self.n % 2 == 0 - } -} - -trait Replaceable { - fn replace(&mut self, substitute: usize) -> usize; -} - -impl Replaceable for MyStruct { - // ↓ N.b.: `#[must_use]` attribute on a particular trait implementation - // method won't work; the attribute should be on the method signature in - // the trait's definition. - #[must_use] - fn replace(&mut self, substitute: usize) -> usize { - let previously = self.n; - self.n = substitute; - previously - } -} - -#[must_use = "it's important"] -fn need_to_use_this_value() -> bool { - false -} - -fn main() { - need_to_use_this_value(); //~ WARN unused return value - - let mut m = MyStruct { n: 2 }; - let n = MyStruct { n: 3 }; - - m.need_to_use_this_method_value(); //~ WARN unused return value - m.is_even(); // trait method! - //~^ WARN unused return value - - m.replace(3); // won't warn (annotation needs to be in trait definition) - - // comparison methods are `must_use` - 2.eq(&3); //~ WARN unused return value - m.eq(&n); //~ WARN unused return value - - // lint includes comparison operators - 2 == 3; //~ WARN unused comparison - m == n; //~ WARN unused comparison -} diff --git a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr b/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr deleted file mode 100644 index d0a8bb525b6..00000000000 --- a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr +++ /dev/null @@ -1,48 +0,0 @@ -warning: unused return value of `need_to_use_this_value` which must be used: it's important - --> $DIR/fn_must_use.rs:61:5 - | -LL | need_to_use_this_value(); //~ WARN unused return value - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: lint level defined here - --> $DIR/fn_must_use.rs:14:9 - | -LL | #![warn(unused_must_use)] - | ^^^^^^^^^^^^^^^ - -warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used - --> $DIR/fn_must_use.rs:66:5 - | -LL | m.need_to_use_this_method_value(); //~ WARN unused return value - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: unused return value of `EvenNature::is_even` which must be used: no side effects - --> $DIR/fn_must_use.rs:67:5 - | -LL | m.is_even(); // trait method! - | ^^^^^^^^^^^^ - -warning: unused return value of `std::cmp::PartialEq::eq` which must be used - --> $DIR/fn_must_use.rs:73:5 - | -LL | 2.eq(&3); //~ WARN unused return value - | ^^^^^^^^^ - -warning: unused return value of `std::cmp::PartialEq::eq` which must be used - --> $DIR/fn_must_use.rs:74:5 - | -LL | m.eq(&n); //~ WARN unused return value - | ^^^^^^^^^ - -warning: unused comparison which must be used - --> $DIR/fn_must_use.rs:77:5 - | -LL | 2 == 3; //~ WARN unused comparison - | ^^^^^^ - -warning: unused comparison which must be used - --> $DIR/fn_must_use.rs:78:5 - | -LL | m == n; //~ WARN unused comparison - | ^^^^^^ - diff --git a/src/test/ui/span/gated-features-attr-spans.rs b/src/test/ui/span/gated-features-attr-spans.rs index 83a4c5d5dd2..eff1f98eb71 100644 --- a/src/test/ui/span/gated-features-attr-spans.rs +++ b/src/test/ui/span/gated-features-attr-spans.rs @@ -8,33 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(attr_literals)] - -#[repr(align(16))] -struct Gem { - mohs_hardness: u8, - poofed: bool, - weapon: Weapon, -} - #[repr(simd)] //~ ERROR are experimental struct Weapon { name: String, damage: u32 } -impl Gem { - #[must_use] fn summon_weapon(&self) -> Weapon { self.weapon } - //~^ WARN is experimental -} - -#[must_use] //~ WARN is experimental -fn bubble(gem: Gem) -> Result { - if gem.poofed { - Ok(gem) - } else { - Err(()) - } -} - fn main() {} diff --git a/src/test/ui/span/gated-features-attr-spans.stderr b/src/test/ui/span/gated-features-attr-spans.stderr index 179daf83c3c..a99530529fc 100644 --- a/src/test/ui/span/gated-features-attr-spans.stderr +++ b/src/test/ui/span/gated-features-attr-spans.stderr @@ -1,27 +1,11 @@ error[E0658]: SIMD types are experimental and possibly buggy (see issue #27731) - --> $DIR/gated-features-attr-spans.rs:20:1 + --> $DIR/gated-features-attr-spans.rs:11:1 | LL | #[repr(simd)] //~ ERROR are experimental | ^^^^^^^^^^^^^ | = help: add #![feature(repr_simd)] to the crate attributes to enable -warning: `#[must_use]` on methods is experimental (see issue #43302) - --> $DIR/gated-features-attr-spans.rs:27:5 - | -LL | #[must_use] fn summon_weapon(&self) -> Weapon { self.weapon } - | ^^^^^^^^^^^ - | - = help: add #![feature(fn_must_use)] to the crate attributes to enable - -warning: `#[must_use]` on functions is experimental (see issue #43302) - --> $DIR/gated-features-attr-spans.rs:31:1 - | -LL | #[must_use] //~ WARN is experimental - | ^^^^^^^^^^^ - | - = help: add #![feature(fn_must_use)] to the crate attributes to enable - error: aborting due to previous error For more information about this error, try `rustc --explain E0658`. -- cgit 1.4.1-3-g733a5 From e5280e452f194ea7b4066c50b7954e07cb054161 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sun, 29 Apr 2018 17:13:49 -0500 Subject: use const trick --- src/liballoc/raw_vec.rs | 29 ++++++----------------------- src/liballoc/vec.rs | 2 +- 2 files changed, 7 insertions(+), 24 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index fe18979fb51..6ca668fda59 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -54,28 +54,18 @@ pub struct RawVec { } impl RawVec { - // FIXME: this should be made `const` when `if` statements are allowed /// 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::() == 0 { !0 } else { 0 }; + // FIXME(mark-i-m): use this line when `if`s are allowed in `const` + //let cap = if mem::size_of::() == 0 { !0 } else { 0 }; // Unique::empty() doubles as "unallocated" and "zero-sized allocation" RawVec { ptr: Unique::empty(), - cap, - a, - } - } - - // FIXME: this should removed when `new_in` can be made `const` - /// Like `empty` but parametrized over the choice of allocator for the returned `RawVec`. - pub const fn empty_in(a: A) -> Self { - // Unique::empty() doubles as "unallocated" and "zero-sized allocation" - RawVec { - ptr: Unique::empty(), - cap: 0, + // FIXME(mark-i-m): use `cap` when ifs are allowed in const + cap: [0, !0][(mem::size_of::() != 0) as usize], a, } } @@ -132,17 +122,10 @@ impl RawVec { /// 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) } - // FIXME: this should removed when `new` can be made `const` - /// Create a `RawVec` with capcity 0 (on the system heap), regardless of `T`, without - /// allocating. - pub const fn empty() -> Self { - Self::empty_in(Global) - } - /// Creates a RawVec (on the system heap) with exactly the /// capacity and alignment requirements for a `[T; cap]`. This is /// equivalent to calling RawVec::new when `cap` is 0 or T is diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 415d75664ff..35d0a69a05a 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -325,7 +325,7 @@ impl Vec { #[rustc_const_unstable(feature = "const_vec_new")] pub const fn new() -> Vec { Vec { - buf: RawVec::empty(), + buf: RawVec::new(), len: 0, } } -- cgit 1.4.1-3-g733a5 From f9f992379de4a82637ec4bf717ff42f27872bc48 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sun, 29 Apr 2018 17:27:17 -0500 Subject: heh, logic is hard --- src/liballoc/raw_vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 6ca668fda59..eb25ae17511 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -65,7 +65,7 @@ impl RawVec { RawVec { ptr: Unique::empty(), // FIXME(mark-i-m): use `cap` when ifs are allowed in const - cap: [0, !0][(mem::size_of::() != 0) as usize], + cap: [0, !0][(mem::size_of::() == 0) as usize], a, } } -- cgit 1.4.1-3-g733a5 From fba903a435ea6e0e3736541cb487586262835e48 Mon Sep 17 00:00:00 2001 From: kennytm Date: Fri, 6 Apr 2018 02:03:22 +0800 Subject: Make the fields of RangeInclusive private. Added new()/start()/end() methods to RangeInclusive. Changed the lowering of `..=` to use RangeInclusive::new(). --- src/liballoc/lib.rs | 2 +- src/liballoc/tests/lib.rs | 2 +- src/libcore/ops/range.rs | 60 +++++++++++++++++++++++++++++++++++++++++++- src/libcore/tests/lib.rs | 2 +- src/librustc/hir/lowering.rs | 16 +++++++++++- src/librustc_trans/lib.rs | 2 +- 6 files changed, 78 insertions(+), 6 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 021395d0c82..c94fe2a2f83 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -122,7 +122,7 @@ #![feature(on_unimplemented)] #![feature(exact_chunks)] #![feature(pointer_methods)] -#![feature(inclusive_range_fields)] +#![feature(inclusive_range_methods)] #![cfg_attr(stage0, feature(generic_param_attrs))] #![cfg_attr(not(test), feature(fn_traits, i128))] diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 32272169307..1c8ff316e55 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -25,7 +25,7 @@ #![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(exact_chunks)] -#![feature(inclusive_range_fields)] +#![feature(inclusive_range_methods)] extern crate alloc_system; extern crate core; diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index d70f7ae66f9..c1bd1ef2d1d 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -320,7 +320,7 @@ impl> RangeTo { /// ``` /// #![feature(inclusive_range_fields)] /// -/// assert_eq!((3..=5), std::ops::RangeInclusive { start: 3, end: 5 }); +/// assert_eq!((3..=5), std::ops::RangeInclusive::new(3, 5)); /// assert_eq!(3 + 4 + 5, (3..=5).sum()); /// /// let arr = [0, 1, 2, 3]; @@ -331,14 +331,72 @@ impl> RangeTo { #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { + // FIXME: The current representation follows RFC 1980, + // but it is known that LLVM is not able to optimize loops following that RFC. + // Consider adding an extra `bool` field to indicate emptiness of the range. + // See #45222 for performance test cases. + #[cfg(not(stage0))] + pub(crate) start: Idx, + #[cfg(not(stage0))] + pub(crate) end: Idx, /// The lower bound of the range (inclusive). + #[cfg(stage0)] #[unstable(feature = "inclusive_range_fields", issue = "49022")] pub start: Idx, /// The upper bound of the range (inclusive). + #[cfg(stage0)] #[unstable(feature = "inclusive_range_fields", issue = "49022")] pub end: Idx, } +impl RangeInclusive { + /// Creates a new inclusive range. Equivalent to writing `start..=end`. + /// + /// # Examples + /// + /// ``` + /// #![feature(inclusive_range_methods)] + /// use std::ops::RangeInclusive; + /// + /// assert_eq!(3..=5, RangeInclusive::new(3, 5)); + /// ``` + #[unstable(feature = "inclusive_range_methods", issue = "49022")] + #[inline] + pub fn new(start: Idx, end: Idx) -> Self { + Self { start, end } + } + + /// Returns the lower bound of the range (inclusive). + /// + /// # Examples + /// + /// ``` + /// #![feature(inclusive_range_methods)] + /// + /// assert_eq!((3..=5).start(), &3); + /// ``` + #[unstable(feature = "inclusive_range_methods", issue = "49022")] + #[inline] + pub fn start(&self) -> &Idx { + &self.start + } + + /// Returns the upper bound of the range (inclusive). + /// + /// # Examples + /// + /// ``` + /// #![feature(inclusive_range_methods)] + /// + /// assert_eq!((3..=5).end(), &5); + /// ``` + #[unstable(feature = "inclusive_range_methods", issue = "49022")] + #[inline] + pub fn end(&self) -> &Idx { + &self.end + } +} + #[stable(feature = "inclusive_range", since = "1.26.0")] impl fmt::Debug for RangeInclusive { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index e4d27717938..f6750c590b3 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -44,7 +44,7 @@ #![feature(exact_chunks)] #![cfg_attr(stage0, feature(atomic_nand))] #![feature(reverse_bits)] -#![feature(inclusive_range_fields)] +#![feature(inclusive_range_methods)] #![feature(iterator_find_map)] extern crate core; diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index e4b9fc1385d..196f7879980 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3119,6 +3119,20 @@ impl<'a> LoweringContext<'a> { ExprKind::Index(ref el, ref er) => { hir::ExprIndex(P(self.lower_expr(el)), P(self.lower_expr(er))) } + // Desugar `..=` to `std::ops::RangeInclusive::new(, )` + ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => { + // FIXME: Use head_sp directly after RangeInclusive::new() is stabilized in stage0. + let span = self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span); + let id = self.lower_node_id(e.id); + let e1 = self.lower_expr(e1); + let e2 = self.lower_expr(e2); + let ty_path = P(self.std_path(span, &["ops", "RangeInclusive"], false)); + let ty = self.ty_path(id, span, hir::QPath::Resolved(None, ty_path)); + let new_seg = P(hir::PathSegment::from_name(Symbol::intern("new"))); + let new_path = hir::QPath::TypeRelative(ty, new_seg); + let new = P(self.expr(span, hir::ExprPath(new_path), ThinVec::new())); + hir::ExprCall(new, hir_vec![e1, e2]) + } ExprKind::Range(ref e1, ref e2, lims) => { use syntax::ast::RangeLimits::*; @@ -3128,7 +3142,7 @@ impl<'a> LoweringContext<'a> { (&None, &Some(..), HalfOpen) => "RangeTo", (&Some(..), &Some(..), HalfOpen) => "Range", (&None, &Some(..), Closed) => "RangeToInclusive", - (&Some(..), &Some(..), Closed) => "RangeInclusive", + (&Some(..), &Some(..), Closed) => unreachable!(), (_, &None, Closed) => self.diagnostic() .span_fatal(e.span, "inclusive range with no end") .raise(), diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 96a10e8b99d..9259fef279f 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -29,7 +29,7 @@ #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] #![feature(optin_builtin_traits)] -#![feature(inclusive_range_fields)] +#![feature(inclusive_range_methods)] use rustc::dep_graph::WorkProduct; use syntax_pos::symbol::Symbol; -- cgit 1.4.1-3-g733a5