Skip to content

Add the identity function as core::convert::identity #47562

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Aug 20, 2018
60 changes: 60 additions & 0 deletions src/libcore/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,66 @@

#![stable(feature = "rust1", since = "1.0.0")]

/// 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 `identity` to do nothing among other interesting functions:
///
/// ```rust
/// #![feature(convert_id)]
/// use std::convert::identity;
///
/// fn manipulation(x: u32) -> u32 {
/// // Let's assume that this function does something interesting.
/// x + 1
/// }
///
/// let _arr = &[identity, manipulation];
/// ```
///
/// Using `identity` to get a function that changes nothing in a conditional:
///
/// ```rust
/// #![feature(convert_id)]
/// use std::convert::identity;
///
/// # let condition = true;
///
/// # fn manipulation(x: u32) -> u32 { x + 1 }
///
/// let do_stuff = if condition { manipulation } else { identity };
///
/// // do more interesting stuff..
///
/// let _results = do_stuff(42);
/// ```
///
/// Using `identity` to keep the `Some` variants of an iterator of `Option<T>`:
///
/// ```rust
/// #![feature(convert_id)]
/// use std::convert::identity;
///
/// let iter = vec![Some(1), None, Some(3)].into_iter();
/// let filtered = iter.filter_map(identity).collect::<Vec<_>>();
/// assert_eq!(vec![1, 3], filtered);
/// ```
#[unstable(feature = "convert_id", issue = "53500")]
#[rustc_const_unstable(feature = "const_convert_id")]
#[inline]
pub const fn identity<T>(x: T) -> T { x }

/// A cheap reference-to-reference conversion. Used to convert a value to a
/// reference value within generic code.
///
Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/rfc-2306/convert-id-const-no-gate.rs
Original file line number Diff line number Diff line change
@@ -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 <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.

// 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);
}
10 changes: 10 additions & 0 deletions src/test/ui/rfc-2306/convert-id-const-no-gate.stderr
Original file line number Diff line number Diff line change
@@ -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

20 changes: 20 additions & 0 deletions src/test/ui/rfc-2306/convert-id-const-with-gate.rs
Original file line number Diff line number Diff line change
@@ -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 <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.

// 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);
}