Skip to content

Commit 2a61f0c

Browse files
address comments
1 parent aeb765b commit 2a61f0c

File tree

4 files changed

+109
-55
lines changed

4 files changed

+109
-55
lines changed

compiler/rustc_typeck/src/check/method/suggest.rs

+23-35
Original file line numberDiff line numberDiff line change
@@ -1375,22 +1375,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13751375
let matching_variants: Vec<_> = kind
13761376
.variants()
13771377
.iter()
1378-
.filter_map(|variant| {
1378+
.flat_map(|variant| {
13791379
let [field] = &variant.fields[..] else { return None; };
13801380
let field_ty = field.ty(tcx, substs);
13811381

13821382
// Skip `_`, since that'll just lead to ambiguity.
1383-
if matches!(self.resolve_vars_if_possible(field_ty).kind(), ty::Infer(_)) {
1383+
if self.resolve_vars_if_possible(field_ty).is_ty_var() {
13841384
return None;
13851385
}
13861386

1387-
if let Ok(pick) =
1388-
self.lookup_probe(span, item_name, field_ty, call_expr, ProbeScope::AllTraits)
1389-
{
1390-
Some((variant, field, pick))
1391-
} else {
1392-
None
1393-
}
1387+
self.lookup_probe(span, item_name, field_ty, call_expr, ProbeScope::AllTraits)
1388+
.ok()
1389+
.map(|pick| (variant, field, pick))
13941390
})
13951391
.collect();
13961392

@@ -1409,45 +1405,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14091405
};
14101406

14111407
match &matching_variants[..] {
1412-
[(_, field, pick)] if Some(kind.did()) == tcx.get_diagnostic_item(sym::Result) => {
1408+
[(_, field, pick)] => {
14131409
let self_ty = field.ty(tcx, substs);
14141410
err.span_note(
14151411
tcx.def_span(pick.item.def_id),
14161412
&format!("the method `{item_name}` exists on the type `{self_ty}`"),
14171413
);
1418-
if ret_ty_matches(sym::Result) {
1419-
err.span_suggestion_verbose(
1420-
expr.span.shrink_to_hi(),
1421-
format!("use the `?` operator to extract the `{self_ty}` value, propagating a `Result::Err` value to the caller"),
1422-
"?".to_owned(),
1423-
Applicability::MachineApplicable,
1424-
);
1425-
} else {
1426-
err.span_suggestion_verbose(
1427-
expr.span.shrink_to_hi(),
1428-
format!("consider using `Result::expect` to unwrap the `{self_ty}` value, panicking if the value is an `Err`"),
1429-
".expect(\"REASON\")".to_owned(),
1430-
Applicability::HasPlaceholders,
1431-
);
1432-
}
1433-
}
1434-
[(_, field, pick)] if Some(kind.did()) == tcx.get_diagnostic_item(sym::Option) => {
1435-
let self_ty = field.ty(tcx, substs);
1436-
err.span_note(
1437-
tcx.def_span(pick.item.def_id),
1438-
&format!("the method `{item_name}` exists on the type `{self_ty}`"),
1439-
);
1440-
if ret_ty_matches(sym::Option) {
1414+
let (article, kind, variant, question) =
1415+
if Some(kind.did()) == tcx.get_diagnostic_item(sym::Result) {
1416+
("a", "Result", "Err", ret_ty_matches(sym::Result))
1417+
} else if Some(kind.did()) == tcx.get_diagnostic_item(sym::Option) {
1418+
("an", "Option", "None", ret_ty_matches(sym::Option))
1419+
} else {
1420+
return;
1421+
};
1422+
if question {
14411423
err.span_suggestion_verbose(
14421424
expr.span.shrink_to_hi(),
1443-
format!("use the `?` operator to extract the `{self_ty}` value, propagating a `None` to the caller"),
1425+
format!(
1426+
"use the `?` operator to extract the `{self_ty}` value, propagating \
1427+
{article} `{kind}::{variant}` value to the caller"
1428+
),
14441429
"?".to_owned(),
14451430
Applicability::MachineApplicable,
14461431
);
14471432
} else {
14481433
err.span_suggestion_verbose(
14491434
expr.span.shrink_to_hi(),
1450-
format!("consider using `Option::expect` to unwrap the `{self_ty}` value, panicking if the value is `None`"),
1435+
format!(
1436+
"consider using `{kind}::expect` to unwrap the `{self_ty}` value, \
1437+
panicking if the value is {article} `{kind}::{variant}`"
1438+
),
14511439
".expect(\"REASON\")".to_owned(),
14521440
Applicability::HasPlaceholders,
14531441
);

src/test/ui/suggestions/enum-method-probe.fixed

+21-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
// compile-flags: --edition=2021
12
// run-rustfix
3+
24
#![allow(unused)]
35

46
struct Foo;
@@ -17,11 +19,26 @@ fn test_result_in_result() -> Result<(), ()> {
1719
Ok(())
1820
}
1921

20-
fn test_result_in_plain() {
22+
async fn async_test_result_in_result() -> Result<(), ()> {
23+
let res: Result<_, ()> = Ok(Foo);
24+
res?.get();
25+
//~^ ERROR no method named `get` found for enum `Result` in the current scope
26+
//~| HELP use the `?` operator
27+
Ok(())
28+
}
29+
30+
fn test_result_in_unit_return() {
31+
let res: Result<_, ()> = Ok(Foo);
32+
res.expect("REASON").get();
33+
//~^ ERROR no method named `get` found for enum `Result` in the current scope
34+
//~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
35+
}
36+
37+
async fn async_test_result_in_unit_return() {
2138
let res: Result<_, ()> = Ok(Foo);
2239
res.expect("REASON").get();
2340
//~^ ERROR no method named `get` found for enum `Result` in the current scope
24-
//~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is an `Err`
41+
//~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
2542
}
2643

2744
fn test_option_in_option() -> Option<()> {
@@ -32,11 +49,11 @@ fn test_option_in_option() -> Option<()> {
3249
Some(())
3350
}
3451

35-
fn test_option_in_plain() {
52+
fn test_option_in_unit_return() {
3653
let res: Option<_> = Some(Foo);
3754
res.expect("REASON").get();
3855
//~^ ERROR no method named `get` found for enum `Option` in the current scope
39-
//~| HELP consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is `None`
56+
//~| HELP consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is an `Option::None`
4057
}
4158

4259
fn main() {}

src/test/ui/suggestions/enum-method-probe.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
// compile-flags: --edition=2021
12
// run-rustfix
3+
24
#![allow(unused)]
35

46
struct Foo;
@@ -17,11 +19,26 @@ fn test_result_in_result() -> Result<(), ()> {
1719
Ok(())
1820
}
1921

20-
fn test_result_in_plain() {
22+
async fn async_test_result_in_result() -> Result<(), ()> {
23+
let res: Result<_, ()> = Ok(Foo);
24+
res.get();
25+
//~^ ERROR no method named `get` found for enum `Result` in the current scope
26+
//~| HELP use the `?` operator
27+
Ok(())
28+
}
29+
30+
fn test_result_in_unit_return() {
31+
let res: Result<_, ()> = Ok(Foo);
32+
res.get();
33+
//~^ ERROR no method named `get` found for enum `Result` in the current scope
34+
//~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
35+
}
36+
37+
async fn async_test_result_in_unit_return() {
2138
let res: Result<_, ()> = Ok(Foo);
2239
res.get();
2340
//~^ ERROR no method named `get` found for enum `Result` in the current scope
24-
//~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is an `Err`
41+
//~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
2542
}
2643

2744
fn test_option_in_option() -> Option<()> {
@@ -32,11 +49,11 @@ fn test_option_in_option() -> Option<()> {
3249
Some(())
3350
}
3451

35-
fn test_option_in_plain() {
52+
fn test_option_in_unit_return() {
3653
let res: Option<_> = Some(Foo);
3754
res.get();
3855
//~^ ERROR no method named `get` found for enum `Option` in the current scope
39-
//~| HELP consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is `None`
56+
//~| HELP consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is an `Option::None`
4057
}
4158

4259
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0599]: no method named `get` found for enum `Result` in the current scope
2-
--> $DIR/enum-method-probe.rs:14:9
2+
--> $DIR/enum-method-probe.rs:24:9
33
|
44
LL | res.get();
55
| ^^^ method not found in `Result<Foo, ()>`
66
|
77
note: the method `get` exists on the type `Foo`
8-
--> $DIR/enum-method-probe.rs:7:5
8+
--> $DIR/enum-method-probe.rs:9:5
99
|
1010
LL | fn get(&self) -> u8 {
1111
| ^^^^^^^^^^^^^^^^^^^
@@ -15,53 +15,85 @@ LL | res?.get();
1515
| +
1616

1717
error[E0599]: no method named `get` found for enum `Result` in the current scope
18-
--> $DIR/enum-method-probe.rs:22:9
18+
--> $DIR/enum-method-probe.rs:39:9
1919
|
2020
LL | res.get();
2121
| ^^^ method not found in `Result<Foo, ()>`
2222
|
2323
note: the method `get` exists on the type `Foo`
24-
--> $DIR/enum-method-probe.rs:7:5
24+
--> $DIR/enum-method-probe.rs:9:5
2525
|
2626
LL | fn get(&self) -> u8 {
2727
| ^^^^^^^^^^^^^^^^^^^
28-
help: consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is an `Err`
28+
help: consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
29+
|
30+
LL | res.expect("REASON").get();
31+
| +++++++++++++++++
32+
33+
error[E0599]: no method named `get` found for enum `Result` in the current scope
34+
--> $DIR/enum-method-probe.rs:16:9
35+
|
36+
LL | res.get();
37+
| ^^^ method not found in `Result<Foo, ()>`
38+
|
39+
note: the method `get` exists on the type `Foo`
40+
--> $DIR/enum-method-probe.rs:9:5
41+
|
42+
LL | fn get(&self) -> u8 {
43+
| ^^^^^^^^^^^^^^^^^^^
44+
help: use the `?` operator to extract the `Foo` value, propagating a `Result::Err` value to the caller
45+
|
46+
LL | res?.get();
47+
| +
48+
49+
error[E0599]: no method named `get` found for enum `Result` in the current scope
50+
--> $DIR/enum-method-probe.rs:32:9
51+
|
52+
LL | res.get();
53+
| ^^^ method not found in `Result<Foo, ()>`
54+
|
55+
note: the method `get` exists on the type `Foo`
56+
--> $DIR/enum-method-probe.rs:9:5
57+
|
58+
LL | fn get(&self) -> u8 {
59+
| ^^^^^^^^^^^^^^^^^^^
60+
help: consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
2961
|
3062
LL | res.expect("REASON").get();
3163
| +++++++++++++++++
3264

3365
error[E0599]: no method named `get` found for enum `Option` in the current scope
34-
--> $DIR/enum-method-probe.rs:29:9
66+
--> $DIR/enum-method-probe.rs:46:9
3567
|
3668
LL | res.get();
3769
| ^^^ method not found in `Option<Foo>`
3870
|
3971
note: the method `get` exists on the type `Foo`
40-
--> $DIR/enum-method-probe.rs:7:5
72+
--> $DIR/enum-method-probe.rs:9:5
4173
|
4274
LL | fn get(&self) -> u8 {
4375
| ^^^^^^^^^^^^^^^^^^^
44-
help: use the `?` operator to extract the `Foo` value, propagating a `None` to the caller
76+
help: use the `?` operator to extract the `Foo` value, propagating an `Option::None` value to the caller
4577
|
4678
LL | res?.get();
4779
| +
4880

4981
error[E0599]: no method named `get` found for enum `Option` in the current scope
50-
--> $DIR/enum-method-probe.rs:37:9
82+
--> $DIR/enum-method-probe.rs:54:9
5183
|
5284
LL | res.get();
5385
| ^^^ method not found in `Option<Foo>`
5486
|
5587
note: the method `get` exists on the type `Foo`
56-
--> $DIR/enum-method-probe.rs:7:5
88+
--> $DIR/enum-method-probe.rs:9:5
5789
|
5890
LL | fn get(&self) -> u8 {
5991
| ^^^^^^^^^^^^^^^^^^^
60-
help: consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is `None`
92+
help: consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is an `Option::None`
6193
|
6294
LL | res.expect("REASON").get();
6395
| +++++++++++++++++
6496

65-
error: aborting due to 4 previous errors
97+
error: aborting due to 6 previous errors
6698

6799
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)