From 351fefbb5969f241d195d3dfc1feab463ab678e1 Mon Sep 17 00:00:00 2001 From: Mazdak Date: Fri, 19 Jan 2018 01:27:59 +0100 Subject: [PATCH 01/11] add fn core::convert::id(x: T) -> T { x } --- src/libcore/convert.rs | 67 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index e815d72d3664..77a87fdf1c6f 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -50,6 +50,73 @@ use fmt; +/// An identity function. Two things are important to note about this function: +/// +/// - It is not always equivalent to a closure like `|x| x` since the +/// closure may coerce `x` into a different type. +/// +/// - It moves the input `x` passed to the function. +/// +/// While it might seem strange to have a function that just returns back the +/// input, there are some interesting uses. +/// +/// # Examples +/// +/// Using `id` to do nothing among other interesting functions: +/// +/// ```rust +/// #![feature(convert_id)] +/// use std::convert::id; +/// +/// fn manipulation(x: u32) -> u32 { +/// // Let's assume that this function does something interesting. +/// x + 1 +/// } +/// +/// let _arr = &[id, manipulation]; +/// ``` +/// +/// Using `id` to get a function that changes nothing in a conditional: +/// +/// ```rust +/// #![feature(convert_id)] +/// use std::convert::id; +/// +/// // Let's pretend we have an interesting condition: +/// let condition = true; +/// +/// let do_stuff = if condition { manipulation } else { id }; +/// +/// // do more interesting stuff.. +/// let _results = do_stuff(42); +/// ``` +/// +/// Using `id` to concatenate an iterator of iterators: +/// +/// ```rust +/// #![feature(convert_id)] +/// use std::convert::id; +/// +/// let vec_vec = vec![vec![1, 3, 4], vec![5, 6]]; +/// let iter_iter = vec_vec.into_iter().map(Vec::into_iter); +/// let concatenated = iter_iter.flat_map(id).collect::>(); +/// assert_eq!(vec![1, 3, 4, 5, 6], concatenated); +/// ``` +/// +/// Using `id` to keep the `Some` variants of an iterator of `Option`: +/// +/// ```rust +/// #![feature(convert_id)] +/// use std::convert::id; +/// +/// let iter = vec![Some(1), None, Some(3)].into_iter(); +/// let filtered = iter.filter_map(id).collect::>(); +/// assert_eq!(vec![1, 3], filtered); +/// ``` +#[unstable(feature = "convert_id", issue = "0")] +#[inline] +pub fn id(x: T) -> T { x } + /// A type used as the error type for implementations of fallible conversion /// traits in cases where conversions cannot actually fail. /// From 651b25a27c2dc05460a86ba18b57d45d98d83aee Mon Sep 17 00:00:00 2001 From: Mazdak Date: Fri, 19 Jan 2018 01:28:25 +0100 Subject: [PATCH 02/11] add fn core::convert::id(x: T) -> T { x } to the prelude --- src/libcore/prelude/v1.rs | 3 +++ src/libstd/prelude/v1.rs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs index d43496c387cb..348cfc97b80c 100644 --- a/src/libcore/prelude/v1.rs +++ b/src/libcore/prelude/v1.rs @@ -28,6 +28,9 @@ pub use ops::{Drop, Fn, FnMut, FnOnce}; #[stable(feature = "core_prelude", since = "1.4.0")] #[doc(no_inline)] pub use mem::drop; +#[unstable(feature = "convert_id_prelude", issue = "0")] +#[inline] +#[doc(no_inline)] pub use convert::id; // Re-exported types and traits #[stable(feature = "core_prelude", since = "1.4.0")] diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs index feedd4e1abe5..190304a1d3e7 100644 --- a/src/libstd/prelude/v1.rs +++ b/src/libstd/prelude/v1.rs @@ -23,6 +23,9 @@ // Re-exported functions #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use mem::drop; +#[unstable(feature = "convert_id_prelude", issue = "0")] +#[inline] +#[doc(no_inline)] pub use convert::id; // Re-exported types and traits #[stable(feature = "rust1", since = "1.0.0")] From 567f040c65808867936f61cfc47d2621a40278bb Mon Sep 17 00:00:00 2001 From: Mazdak Date: Fri, 19 Jan 2018 02:41:58 +0100 Subject: [PATCH 03/11] fix prelude reexport of convert::id --- src/libcore/prelude/v1.rs | 4 ++-- src/libstd/prelude/v1.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs index 348cfc97b80c..6f4f273a31f5 100644 --- a/src/libcore/prelude/v1.rs +++ b/src/libcore/prelude/v1.rs @@ -29,8 +29,8 @@ pub use ops::{Drop, Fn, FnMut, FnOnce}; #[doc(no_inline)] pub use mem::drop; #[unstable(feature = "convert_id_prelude", issue = "0")] -#[inline] -#[doc(no_inline)] pub use convert::id; +#[doc(no_inline)] +pub use convert::id; // Re-exported types and traits #[stable(feature = "core_prelude", since = "1.4.0")] diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs index 190304a1d3e7..d256353ab307 100644 --- a/src/libstd/prelude/v1.rs +++ b/src/libstd/prelude/v1.rs @@ -24,8 +24,8 @@ #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use mem::drop; #[unstable(feature = "convert_id_prelude", issue = "0")] -#[inline] -#[doc(no_inline)] pub use convert::id; +#[doc(no_inline)] +pub use convert::id; // Re-exported types and traits #[stable(feature = "rust1", since = "1.0.0")] From 93debaa306cd968de12c3084d38083c78349054b Mon Sep 17 00:00:00 2001 From: Mazdak Date: Fri, 19 Jan 2018 02:48:02 +0100 Subject: [PATCH 04/11] add #![feature(convert_id)] to libstd + libcore --- src/libcore/lib.rs | 1 + src/libstd/lib.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index d5190b65863c..c49292481c3f 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -72,6 +72,7 @@ #![feature(cfg_target_has_atomic)] #![feature(concat_idents)] #![feature(const_fn)] +#![feature(convert_id)] #![feature(custom_attribute)] #![feature(fundamental)] #![feature(i128_type)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index bb38fc550917..880b46fa5071 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -256,6 +256,7 @@ #![feature(collections_range)] #![feature(compiler_builtins_lib)] #![feature(const_fn)] +#![feature(convert_id)] #![feature(core_float)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] From ac64ef33756d05557153e00211cdf8fcf65d4be3 Mon Sep 17 00:00:00 2001 From: Mazdak Date: Fri, 19 Jan 2018 03:11:57 +0100 Subject: [PATCH 05/11] fix doctests for convert::id --- src/libcore/convert.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 77a87fdf1c6f..41eb1eed4e46 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -82,12 +82,14 @@ use fmt; /// #![feature(convert_id)] /// use std::convert::id; /// -/// // Let's pretend we have an interesting condition: -/// let condition = true; +/// # let condition = true; +/// +/// # fn manipulation(x: u32) -> u32 { x + 1 } /// /// let do_stuff = if condition { manipulation } else { id }; /// /// // do more interesting stuff.. +/// /// let _results = do_stuff(42); /// ``` /// From 8208c77782d80634714b7ecd6ad5750a4c4663dc Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 19 Aug 2018 18:36:18 +0200 Subject: [PATCH 06/11] Drop `identity` from prelude. --- src/libcore/prelude/v1.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs index 7c5738e94e54..45f629a64424 100644 --- a/src/libcore/prelude/v1.rs +++ b/src/libcore/prelude/v1.rs @@ -28,9 +28,6 @@ pub use ops::{Drop, Fn, FnMut, FnOnce}; #[stable(feature = "core_prelude", since = "1.4.0")] #[doc(no_inline)] pub use mem::drop; -#[unstable(feature = "convert_id_prelude", issue = "0")] -#[doc(no_inline)] -pub use convert::id; // Re-exported types and traits #[stable(feature = "core_prelude", since = "1.4.0")] From c2217b7fb7d0c2d5383335d8958e0d26263a7904 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 19 Aug 2018 18:37:00 +0200 Subject: [PATCH 07/11] Get rid of unnecessary #![feature(core_float)]. --- src/libstd/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index b1d45b7f260e..2a36b78d79ca 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -252,7 +252,6 @@ #![feature(char_error_internals)] #![feature(compiler_builtins_lib)] #![feature(const_fn)] -#![feature(core_float)] #![feature(const_int_ops)] #![feature(const_ip)] #![feature(convert_id)] From 71187b7e187823f997ab0481a37c2a4b0ccafe7e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 19 Aug 2018 18:49:31 +0200 Subject: [PATCH 08/11] Make core::convert::identity a const fn. --- src/libcore/convert.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 67cb010c6b41..bfa1bd99bfe4 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -104,8 +104,9 @@ /// assert_eq!(vec![1, 3], filtered); /// ``` #[unstable(feature = "convert_id", issue = "0")] +#[rustc_const_unstable(feature = "const_convert_id")] #[inline] -pub fn identity(x: T) -> T { x } +pub const fn identity(x: T) -> T { x } /// A cheap reference-to-reference conversion. Used to convert a value to a /// reference value within generic code. From f84ec02bf7118f50c785326e1c5493c07279f3ed Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 19 Aug 2018 19:25:35 +0200 Subject: [PATCH 09/11] remove feature(convert_id) from lib{core,std}/lib.rs --- src/libcore/lib.rs | 1 - src/libstd/lib.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 055da19de60d..e85bf1dfcad2 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -83,7 +83,6 @@ #![feature(const_fn)] #![feature(const_int_ops)] #![feature(const_fn_union)] -#![feature(convert_id)] #![feature(custom_attribute)] #![feature(doc_cfg)] #![feature(doc_spotlight)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 2a36b78d79ca..b0069f826eef 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -254,7 +254,6 @@ #![feature(const_fn)] #![feature(const_int_ops)] #![feature(const_ip)] -#![feature(convert_id)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] #![feature(exact_size_is_empty)] From b7772e6c9e27cb4bbdcb735789b937dc63ca189b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 19 Aug 2018 21:06:43 +0200 Subject: [PATCH 10/11] convert-id: tests for const gating. --- .../ui/rfc-2306/convert-id-const-no-gate.rs | 17 ++++++++++++++++ .../rfc-2306/convert-id-const-no-gate.stderr | 10 ++++++++++ .../ui/rfc-2306/convert-id-const-with-gate.rs | 20 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 src/test/ui/rfc-2306/convert-id-const-no-gate.rs create mode 100644 src/test/ui/rfc-2306/convert-id-const-no-gate.stderr create mode 100644 src/test/ui/rfc-2306/convert-id-const-with-gate.rs diff --git a/src/test/ui/rfc-2306/convert-id-const-no-gate.rs b/src/test/ui/rfc-2306/convert-id-const-no-gate.rs new file mode 100644 index 000000000000..545c179dec9f --- /dev/null +++ b/src/test/ui/rfc-2306/convert-id-const-no-gate.rs @@ -0,0 +1,17 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This test should fail since identity is not stable as a const fn yet. + +#![feature(convert_id)] + +fn main() { + const _FOO: u8 = ::std::convert::identity(42u8); +} diff --git a/src/test/ui/rfc-2306/convert-id-const-no-gate.stderr b/src/test/ui/rfc-2306/convert-id-const-no-gate.stderr new file mode 100644 index 000000000000..dfd8619d8751 --- /dev/null +++ b/src/test/ui/rfc-2306/convert-id-const-no-gate.stderr @@ -0,0 +1,10 @@ +error: `std::convert::identity` is not yet stable as a const fn + --> $DIR/convert-id-const-no-gate.rs:16:22 + | +LL | const _FOO: u8 = ::std::convert::identity(42u8); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: in Nightly builds, add `#![feature(const_convert_id)]` to the crate attributes to enable + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2306/convert-id-const-with-gate.rs b/src/test/ui/rfc-2306/convert-id-const-with-gate.rs new file mode 100644 index 000000000000..c546f11914f8 --- /dev/null +++ b/src/test/ui/rfc-2306/convert-id-const-with-gate.rs @@ -0,0 +1,20 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This test should pass since we've opted into 'identity' as an +// unstable const fn. + +// compile-pass + +#![feature(convert_id, const_convert_id)] + +fn main() { + const _FOO: u8 = ::std::convert::identity(42u8); +} From 86641d97b23674a7b0df8523a8684e8b02bf0b33 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 20 Aug 2018 09:16:56 +0200 Subject: [PATCH 11/11] core::convert::identity: fix issue number to #53500 --- src/libcore/convert.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index bfa1bd99bfe4..d5337868843d 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -103,7 +103,7 @@ /// let filtered = iter.filter_map(identity).collect::>(); /// assert_eq!(vec![1, 3], filtered); /// ``` -#[unstable(feature = "convert_id", issue = "0")] +#[unstable(feature = "convert_id", issue = "53500")] #[rustc_const_unstable(feature = "const_convert_id")] #[inline] pub const fn identity(x: T) -> T { x }