Skip to content

Commit b873fa6

Browse files
committed
Auto merge of #76136 - CDirkx:const-result, r=dtolnay
Stabilize some Result methods as const Stabilize the following methods of Result as const: - `is_ok` - `is_err` - `as_ref` A test is also included, analogous to the test for `const_option`. These methods are currently const under the unstable feature `const_result` (tracking issue: #67520). I believe these methods to be eligible for stabilization because of the stabilization of #49146 (Allow if and match in constants) and the trivial implementations, see also: [PR#75463](#75463) and [PR#76135](#76135). Note: these methods are the only methods currently under the `const_result` feature, thus this PR results in the removal of the feature. Related: #76225
2 parents 41507ed + bf70e21 commit b873fa6

10 files changed

+116
-191
lines changed

library/core/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@
8787
#![feature(const_ptr_offset)]
8888
#![feature(const_ptr_offset_from)]
8989
#![feature(const_raw_ptr_comparison)]
90-
#![feature(const_result)]
9190
#![feature(const_slice_from_raw_parts)]
9291
#![feature(const_slice_ptr_len)]
9392
#![feature(const_size_of_val)]

library/core/src/result.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ impl<T, E> Result<T, E> {
273273
/// assert_eq!(x.is_ok(), false);
274274
/// ```
275275
#[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"]
276-
#[rustc_const_unstable(feature = "const_result", issue = "67520")]
276+
#[rustc_const_stable(feature = "const_result", since = "1.48.0")]
277277
#[inline]
278278
#[stable(feature = "rust1", since = "1.0.0")]
279279
pub const fn is_ok(&self) -> bool {
@@ -294,7 +294,7 @@ impl<T, E> Result<T, E> {
294294
/// assert_eq!(x.is_err(), true);
295295
/// ```
296296
#[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"]
297-
#[rustc_const_unstable(feature = "const_result", issue = "67520")]
297+
#[rustc_const_stable(feature = "const_result", since = "1.48.0")]
298298
#[inline]
299299
#[stable(feature = "rust1", since = "1.0.0")]
300300
pub const fn is_err(&self) -> bool {
@@ -438,7 +438,7 @@ impl<T, E> Result<T, E> {
438438
/// assert_eq!(x.as_ref(), Err(&"Error"));
439439
/// ```
440440
#[inline]
441-
#[rustc_const_unstable(feature = "const_result", issue = "67520")]
441+
#[rustc_const_stable(feature = "const_result", since = "1.48.0")]
442442
#[stable(feature = "rust1", since = "1.0.0")]
443443
pub const fn as_ref(&self) -> Result<&T, &E> {
444444
match *self {

library/core/tests/result.rs

+16
Original file line numberDiff line numberDiff line change
@@ -304,3 +304,19 @@ fn test_result_as_deref_mut() {
304304
let expected_result = Result::Err::<&mut u32, &mut Vec<i32>>(&mut expected_vec);
305305
assert_eq!(mut_err.as_deref_mut(), expected_result);
306306
}
307+
308+
#[test]
309+
fn result_const() {
310+
// test that the methods of `Result` are usable in a const context
311+
312+
const RESULT: Result<usize, bool> = Ok(32);
313+
314+
const REF: Result<&usize, &bool> = RESULT.as_ref();
315+
assert_eq!(REF, Ok(&32));
316+
317+
const IS_OK: bool = RESULT.is_ok();
318+
assert!(IS_OK);
319+
320+
const IS_ERR: bool = RESULT.is_err();
321+
assert!(!IS_ERR)
322+
}

src/tools/clippy/clippy_lints/src/matches.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1469,10 +1469,10 @@ mod redundant_pattern_match {
14691469
keyword: &'static str,
14701470
) {
14711471
fn find_suggestion(cx: &LateContext<'_>, hir_id: HirId, path: &QPath<'_>) -> Option<&'static str> {
1472-
if match_qpath(path, &paths::RESULT_OK) && can_suggest(cx, hir_id, sym!(result_type), "is_ok") {
1472+
if match_qpath(path, &paths::RESULT_OK) {
14731473
return Some("is_ok()");
14741474
}
1475-
if match_qpath(path, &paths::RESULT_ERR) && can_suggest(cx, hir_id, sym!(result_type), "is_err") {
1475+
if match_qpath(path, &paths::RESULT_ERR) {
14761476
return Some("is_err()");
14771477
}
14781478
if match_qpath(path, &paths::OPTION_SOME) && can_suggest(cx, hir_id, sym!(option_type), "is_some") {
@@ -1562,8 +1562,8 @@ mod redundant_pattern_match {
15621562
&paths::RESULT_ERR,
15631563
"is_ok()",
15641564
"is_err()",
1565-
|| can_suggest(cx, hir_id, sym!(result_type), "is_ok"),
1566-
|| can_suggest(cx, hir_id, sym!(result_type), "is_err"),
1565+
|| true,
1566+
|| true,
15671567
)
15681568
} else {
15691569
None

src/tools/clippy/tests/ui/redundant_pattern_matching.fixed

+18-17
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ fn main() {
7777

7878
issue5504();
7979
issue5697();
80+
issue6067();
8081

8182
let _ = if gen_opt().is_some() {
8283
1
@@ -131,31 +132,14 @@ fn issue5504() {
131132
// None of these should be linted because none of the suggested methods
132133
// are `const fn` without toggling a feature.
133134
const fn issue5697() {
134-
if let Ok(_) = Ok::<i32, i32>(42) {}
135-
136-
if let Err(_) = Err::<i32, i32>(42) {}
137-
138135
if let Some(_) = Some(42) {}
139136

140137
if let None = None::<()> {}
141138

142-
while let Ok(_) = Ok::<i32, i32>(10) {}
143-
144-
while let Err(_) = Ok::<i32, i32>(10) {}
145-
146139
while let Some(_) = Some(42) {}
147140

148141
while let None = None::<()> {}
149142

150-
match Ok::<i32, i32>(42) {
151-
Ok(_) => true,
152-
Err(_) => false,
153-
};
154-
155-
match Err::<i32, i32>(42) {
156-
Ok(_) => false,
157-
Err(_) => true,
158-
};
159143
match Some(42) {
160144
Some(_) => true,
161145
None => false,
@@ -166,3 +150,20 @@ const fn issue5697() {
166150
None => true,
167151
};
168152
}
153+
154+
// Methods that are unstable const should not be suggested within a const context, see issue #5697.
155+
// However, in Rust 1.48.0 the methods `is_ok` and `is_err` of `Result` were stabilized as const,
156+
// so the following should be linted.
157+
const fn issue6067() {
158+
if Ok::<i32, i32>(42).is_ok() {}
159+
160+
if Err::<i32, i32>(42).is_err() {}
161+
162+
while Ok::<i32, i32>(10).is_ok() {}
163+
164+
while Ok::<i32, i32>(10).is_err() {}
165+
166+
Ok::<i32, i32>(42).is_ok();
167+
168+
Err::<i32, i32>(42).is_err();
169+
}

src/tools/clippy/tests/ui/redundant_pattern_matching.rs

+24-17
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ fn main() {
9898

9999
issue5504();
100100
issue5697();
101+
issue6067();
101102

102103
let _ = if let Some(_) = gen_opt() {
103104
1
@@ -152,31 +153,14 @@ fn issue5504() {
152153
// None of these should be linted because none of the suggested methods
153154
// are `const fn` without toggling a feature.
154155
const fn issue5697() {
155-
if let Ok(_) = Ok::<i32, i32>(42) {}
156-
157-
if let Err(_) = Err::<i32, i32>(42) {}
158-
159156
if let Some(_) = Some(42) {}
160157

161158
if let None = None::<()> {}
162159

163-
while let Ok(_) = Ok::<i32, i32>(10) {}
164-
165-
while let Err(_) = Ok::<i32, i32>(10) {}
166-
167160
while let Some(_) = Some(42) {}
168161

169162
while let None = None::<()> {}
170163

171-
match Ok::<i32, i32>(42) {
172-
Ok(_) => true,
173-
Err(_) => false,
174-
};
175-
176-
match Err::<i32, i32>(42) {
177-
Ok(_) => false,
178-
Err(_) => true,
179-
};
180164
match Some(42) {
181165
Some(_) => true,
182166
None => false,
@@ -187,3 +171,26 @@ const fn issue5697() {
187171
None => true,
188172
};
189173
}
174+
175+
// Methods that are unstable const should not be suggested within a const context, see issue #5697.
176+
// However, in Rust 1.48.0 the methods `is_ok` and `is_err` of `Result` were stabilized as const,
177+
// so the following should be linted.
178+
const fn issue6067() {
179+
if let Ok(_) = Ok::<i32, i32>(42) {}
180+
181+
if let Err(_) = Err::<i32, i32>(42) {}
182+
183+
while let Ok(_) = Ok::<i32, i32>(10) {}
184+
185+
while let Err(_) = Ok::<i32, i32>(10) {}
186+
187+
match Ok::<i32, i32>(42) {
188+
Ok(_) => true,
189+
Err(_) => false,
190+
};
191+
192+
match Err::<i32, i32>(42) {
193+
Ok(_) => false,
194+
Err(_) => true,
195+
};
196+
}

src/tools/clippy/tests/ui/redundant_pattern_matching.stderr

+51-9
Original file line numberDiff line numberDiff line change
@@ -149,52 +149,94 @@ LL | let x = if let Some(_) = opt { true } else { false };
149149
| -------^^^^^^^------ help: try this: `if opt.is_some()`
150150

151151
error: redundant pattern matching, consider using `is_some()`
152-
--> $DIR/redundant_pattern_matching.rs:102:20
152+
--> $DIR/redundant_pattern_matching.rs:103:20
153153
|
154154
LL | let _ = if let Some(_) = gen_opt() {
155155
| -------^^^^^^^------------ help: try this: `if gen_opt().is_some()`
156156

157157
error: redundant pattern matching, consider using `is_none()`
158-
--> $DIR/redundant_pattern_matching.rs:104:19
158+
--> $DIR/redundant_pattern_matching.rs:105:19
159159
|
160160
LL | } else if let None = gen_opt() {
161161
| -------^^^^------------ help: try this: `if gen_opt().is_none()`
162162

163163
error: redundant pattern matching, consider using `is_ok()`
164-
--> $DIR/redundant_pattern_matching.rs:106:19
164+
--> $DIR/redundant_pattern_matching.rs:107:19
165165
|
166166
LL | } else if let Ok(_) = gen_res() {
167167
| -------^^^^^------------ help: try this: `if gen_res().is_ok()`
168168

169169
error: redundant pattern matching, consider using `is_err()`
170-
--> $DIR/redundant_pattern_matching.rs:108:19
170+
--> $DIR/redundant_pattern_matching.rs:109:19
171171
|
172172
LL | } else if let Err(_) = gen_res() {
173173
| -------^^^^^^------------ help: try this: `if gen_res().is_err()`
174174

175175
error: redundant pattern matching, consider using `is_some()`
176-
--> $DIR/redundant_pattern_matching.rs:141:19
176+
--> $DIR/redundant_pattern_matching.rs:142:19
177177
|
178178
LL | while let Some(_) = r#try!(result_opt()) {}
179179
| ----------^^^^^^^----------------------- help: try this: `while r#try!(result_opt()).is_some()`
180180

181181
error: redundant pattern matching, consider using `is_some()`
182-
--> $DIR/redundant_pattern_matching.rs:142:16
182+
--> $DIR/redundant_pattern_matching.rs:143:16
183183
|
184184
LL | if let Some(_) = r#try!(result_opt()) {}
185185
| -------^^^^^^^----------------------- help: try this: `if r#try!(result_opt()).is_some()`
186186

187187
error: redundant pattern matching, consider using `is_some()`
188-
--> $DIR/redundant_pattern_matching.rs:148:12
188+
--> $DIR/redundant_pattern_matching.rs:149:12
189189
|
190190
LL | if let Some(_) = m!() {}
191191
| -------^^^^^^^------- help: try this: `if m!().is_some()`
192192

193193
error: redundant pattern matching, consider using `is_some()`
194-
--> $DIR/redundant_pattern_matching.rs:149:15
194+
--> $DIR/redundant_pattern_matching.rs:150:15
195195
|
196196
LL | while let Some(_) = m!() {}
197197
| ----------^^^^^^^------- help: try this: `while m!().is_some()`
198198

199-
error: aborting due to 29 previous errors
199+
error: redundant pattern matching, consider using `is_ok()`
200+
--> $DIR/redundant_pattern_matching.rs:179:12
201+
|
202+
LL | if let Ok(_) = Ok::<i32, i32>(42) {}
203+
| -------^^^^^--------------------- help: try this: `if Ok::<i32, i32>(42).is_ok()`
204+
205+
error: redundant pattern matching, consider using `is_err()`
206+
--> $DIR/redundant_pattern_matching.rs:181:12
207+
|
208+
LL | if let Err(_) = Err::<i32, i32>(42) {}
209+
| -------^^^^^^---------------------- help: try this: `if Err::<i32, i32>(42).is_err()`
210+
211+
error: redundant pattern matching, consider using `is_ok()`
212+
--> $DIR/redundant_pattern_matching.rs:183:15
213+
|
214+
LL | while let Ok(_) = Ok::<i32, i32>(10) {}
215+
| ----------^^^^^--------------------- help: try this: `while Ok::<i32, i32>(10).is_ok()`
216+
217+
error: redundant pattern matching, consider using `is_err()`
218+
--> $DIR/redundant_pattern_matching.rs:185:15
219+
|
220+
LL | while let Err(_) = Ok::<i32, i32>(10) {}
221+
| ----------^^^^^^--------------------- help: try this: `while Ok::<i32, i32>(10).is_err()`
222+
223+
error: redundant pattern matching, consider using `is_ok()`
224+
--> $DIR/redundant_pattern_matching.rs:187:5
225+
|
226+
LL | / match Ok::<i32, i32>(42) {
227+
LL | | Ok(_) => true,
228+
LL | | Err(_) => false,
229+
LL | | };
230+
| |_____^ help: try this: `Ok::<i32, i32>(42).is_ok()`
231+
232+
error: redundant pattern matching, consider using `is_err()`
233+
--> $DIR/redundant_pattern_matching.rs:192:5
234+
|
235+
LL | / match Err::<i32, i32>(42) {
236+
LL | | Ok(_) => false,
237+
LL | | Err(_) => true,
238+
LL | | };
239+
| |_____^ help: try this: `Err::<i32, i32>(42).is_err()`
240+
241+
error: aborting due to 35 previous errors
200242

src/tools/clippy/tests/ui/redundant_pattern_matching_const_result.fixed

-44
This file was deleted.

0 commit comments

Comments
 (0)