Skip to content

Commit bf1e461

Browse files
committed
Auto merge of #47562 - Centril:feature/core_convert_id, r=oli-obk
Add the identity function as core::convert::identity ## New notes This implements rust-lang/rfcs#2306 (see #53500). ## Old notes (ignore this in new reviews) Adds the identity function `fn id<T>(x: T) -> T { x }` to core::convert and the prelude. Some motivations for why this is useful are explained in the doc tests. Another is that using the identity function instead of `{ x }` or `|x| x` makes it clear that you intended to use an identity conversion on purpose. The reasoning: + behind adding this to `convert` and not `mem` is that this is an identity *conversion*. + for adding this to the prelude is that it should be easy enough to use that the ease of writing your own identity function or using a closure `|x| x` doesn't overtake that. I've separated this out into two feature gates so that the addition to the prelude can be considered and stabilized separately. cc @bluss
2 parents 758239c + 86641d9 commit bf1e461

File tree

4 files changed

+107
-0
lines changed

4 files changed

+107
-0
lines changed

Diff for: src/libcore/convert.rs

+60
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,66 @@
4848
4949
#![stable(feature = "rust1", since = "1.0.0")]
5050

51+
/// An identity function.
52+
///
53+
/// Two things are important to note about this function:
54+
///
55+
/// - It is not always equivalent to a closure like `|x| x` since the
56+
/// closure may coerce `x` into a different type.
57+
///
58+
/// - It moves the input `x` passed to the function.
59+
///
60+
/// While it might seem strange to have a function that just returns back the
61+
/// input, there are some interesting uses.
62+
///
63+
/// # Examples
64+
///
65+
/// Using `identity` to do nothing among other interesting functions:
66+
///
67+
/// ```rust
68+
/// #![feature(convert_id)]
69+
/// use std::convert::identity;
70+
///
71+
/// fn manipulation(x: u32) -> u32 {
72+
/// // Let's assume that this function does something interesting.
73+
/// x + 1
74+
/// }
75+
///
76+
/// let _arr = &[identity, manipulation];
77+
/// ```
78+
///
79+
/// Using `identity` to get a function that changes nothing in a conditional:
80+
///
81+
/// ```rust
82+
/// #![feature(convert_id)]
83+
/// use std::convert::identity;
84+
///
85+
/// # let condition = true;
86+
///
87+
/// # fn manipulation(x: u32) -> u32 { x + 1 }
88+
///
89+
/// let do_stuff = if condition { manipulation } else { identity };
90+
///
91+
/// // do more interesting stuff..
92+
///
93+
/// let _results = do_stuff(42);
94+
/// ```
95+
///
96+
/// Using `identity` to keep the `Some` variants of an iterator of `Option<T>`:
97+
///
98+
/// ```rust
99+
/// #![feature(convert_id)]
100+
/// use std::convert::identity;
101+
///
102+
/// let iter = vec![Some(1), None, Some(3)].into_iter();
103+
/// let filtered = iter.filter_map(identity).collect::<Vec<_>>();
104+
/// assert_eq!(vec![1, 3], filtered);
105+
/// ```
106+
#[unstable(feature = "convert_id", issue = "53500")]
107+
#[rustc_const_unstable(feature = "const_convert_id")]
108+
#[inline]
109+
pub const fn identity<T>(x: T) -> T { x }
110+
51111
/// A cheap reference-to-reference conversion. Used to convert a value to a
52112
/// reference value within generic code.
53113
///

Diff for: src/test/ui/rfc-2306/convert-id-const-no-gate.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// This test should fail since identity is not stable as a const fn yet.
12+
13+
#![feature(convert_id)]
14+
15+
fn main() {
16+
const _FOO: u8 = ::std::convert::identity(42u8);
17+
}

Diff for: src/test/ui/rfc-2306/convert-id-const-no-gate.stderr

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: `std::convert::identity` is not yet stable as a const fn
2+
--> $DIR/convert-id-const-no-gate.rs:16:22
3+
|
4+
LL | const _FOO: u8 = ::std::convert::identity(42u8);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= help: in Nightly builds, add `#![feature(const_convert_id)]` to the crate attributes to enable
8+
9+
error: aborting due to previous error
10+

Diff for: src/test/ui/rfc-2306/convert-id-const-with-gate.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// This test should pass since we've opted into 'identity' as an
12+
// unstable const fn.
13+
14+
// compile-pass
15+
16+
#![feature(convert_id, const_convert_id)]
17+
18+
fn main() {
19+
const _FOO: u8 = ::std::convert::identity(42u8);
20+
}

0 commit comments

Comments
 (0)