about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-05-30 14:18:03 -0700
committerMichael Goulet <michael@errs.io>2022-05-30 14:23:15 -0700
commit2a61f0cc45c809c62dd149477cb2672c2022c3a4 (patch)
treef3b77c7854f0f5bf8cbc9de04f04d7b6646c15aa
parentaeb765b299640ee0674d2c01df600c296af7d691 (diff)
downloadrust-2a61f0cc45c809c62dd149477cb2672c2022c3a4.tar.gz
rust-2a61f0cc45c809c62dd149477cb2672c2022c3a4.zip
address comments
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs58
-rw-r--r--src/test/ui/suggestions/enum-method-probe.fixed25
-rw-r--r--src/test/ui/suggestions/enum-method-probe.rs25
-rw-r--r--src/test/ui/suggestions/enum-method-probe.stderr56
4 files changed, 109 insertions, 55 deletions
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index b5fd3eb4462..0e198907c8d 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -1375,22 +1375,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let matching_variants: Vec<_> = kind
             .variants()
             .iter()
-            .filter_map(|variant| {
+            .flat_map(|variant| {
                 let [field] = &variant.fields[..] else { return None; };
                 let field_ty = field.ty(tcx, substs);
 
                 // Skip `_`, since that'll just lead to ambiguity.
-                if matches!(self.resolve_vars_if_possible(field_ty).kind(), ty::Infer(_)) {
+                if self.resolve_vars_if_possible(field_ty).is_ty_var() {
                     return None;
                 }
 
-                if let Ok(pick) =
-                    self.lookup_probe(span, item_name, field_ty, call_expr, ProbeScope::AllTraits)
-                {
-                    Some((variant, field, pick))
-                } else {
-                    None
-                }
+                self.lookup_probe(span, item_name, field_ty, call_expr, ProbeScope::AllTraits)
+                    .ok()
+                    .map(|pick| (variant, field, pick))
             })
             .collect();
 
@@ -1409,45 +1405,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         match &matching_variants[..] {
-            [(_, field, pick)] if Some(kind.did()) == tcx.get_diagnostic_item(sym::Result) => {
+            [(_, field, pick)] => {
                 let self_ty = field.ty(tcx, substs);
                 err.span_note(
                     tcx.def_span(pick.item.def_id),
                     &format!("the method `{item_name}` exists on the type `{self_ty}`"),
                 );
-                if ret_ty_matches(sym::Result) {
-                    err.span_suggestion_verbose(
-                        expr.span.shrink_to_hi(),
-                        format!("use the `?` operator to extract the `{self_ty}` value, propagating a `Result::Err` value to the caller"),
-                        "?".to_owned(),
-                        Applicability::MachineApplicable,
-                    );
-                } else {
-                    err.span_suggestion_verbose(
-                        expr.span.shrink_to_hi(),
-                        format!("consider using `Result::expect` to unwrap the `{self_ty}` value, panicking if the value is an `Err`"),
-                        ".expect(\"REASON\")".to_owned(),
-                        Applicability::HasPlaceholders,
-                    );
-                }
-            }
-            [(_, field, pick)] if Some(kind.did()) == tcx.get_diagnostic_item(sym::Option) => {
-                let self_ty = field.ty(tcx, substs);
-                err.span_note(
-                    tcx.def_span(pick.item.def_id),
-                    &format!("the method `{item_name}` exists on the type `{self_ty}`"),
-                );
-                if ret_ty_matches(sym::Option) {
+                let (article, kind, variant, question) =
+                    if Some(kind.did()) == tcx.get_diagnostic_item(sym::Result) {
+                        ("a", "Result", "Err", ret_ty_matches(sym::Result))
+                    } else if Some(kind.did()) == tcx.get_diagnostic_item(sym::Option) {
+                        ("an", "Option", "None", ret_ty_matches(sym::Option))
+                    } else {
+                        return;
+                    };
+                if question {
                     err.span_suggestion_verbose(
                         expr.span.shrink_to_hi(),
-                        format!("use the `?` operator to extract the `{self_ty}` value, propagating a `None` to the caller"),
+                        format!(
+                            "use the `?` operator to extract the `{self_ty}` value, propagating \
+                            {article} `{kind}::{variant}` value to the caller"
+                        ),
                         "?".to_owned(),
                         Applicability::MachineApplicable,
                     );
                 } else {
                     err.span_suggestion_verbose(
                         expr.span.shrink_to_hi(),
-                        format!("consider using `Option::expect` to unwrap the `{self_ty}` value, panicking if the value is `None`"),
+                        format!(
+                            "consider using `{kind}::expect` to unwrap the `{self_ty}` value, \
+                             panicking if the value is {article} `{kind}::{variant}`"
+                        ),
                         ".expect(\"REASON\")".to_owned(),
                         Applicability::HasPlaceholders,
                     );
diff --git a/src/test/ui/suggestions/enum-method-probe.fixed b/src/test/ui/suggestions/enum-method-probe.fixed
index 990f7900f22..6499c92bc6f 100644
--- a/src/test/ui/suggestions/enum-method-probe.fixed
+++ b/src/test/ui/suggestions/enum-method-probe.fixed
@@ -1,4 +1,6 @@
+// compile-flags: --edition=2021
 // run-rustfix
+
 #![allow(unused)]
 
 struct Foo;
@@ -17,11 +19,26 @@ fn test_result_in_result() -> Result<(), ()> {
     Ok(())
 }
 
-fn test_result_in_plain() {
+async fn async_test_result_in_result() -> Result<(), ()> {
+    let res: Result<_, ()> = Ok(Foo);
+    res?.get();
+    //~^ ERROR no method named `get` found for enum `Result` in the current scope
+    //~| HELP use the `?` operator
+    Ok(())
+}
+
+fn test_result_in_unit_return() {
+    let res: Result<_, ()> = Ok(Foo);
+    res.expect("REASON").get();
+    //~^ ERROR no method named `get` found for enum `Result` in the current scope
+    //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
+}
+
+async fn async_test_result_in_unit_return() {
     let res: Result<_, ()> = Ok(Foo);
     res.expect("REASON").get();
     //~^ ERROR no method named `get` found for enum `Result` in the current scope
-    //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is an `Err`
+    //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
 }
 
 fn test_option_in_option() -> Option<()> {
@@ -32,11 +49,11 @@ fn test_option_in_option() -> Option<()> {
     Some(())
 }
 
-fn test_option_in_plain() {
+fn test_option_in_unit_return() {
     let res: Option<_> = Some(Foo);
     res.expect("REASON").get();
     //~^ ERROR no method named `get` found for enum `Option` in the current scope
-    //~| HELP consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is `None`
+    //~| HELP consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is an `Option::None`
 }
 
 fn main() {}
diff --git a/src/test/ui/suggestions/enum-method-probe.rs b/src/test/ui/suggestions/enum-method-probe.rs
index 6270fa9fea5..18ea8ed8a58 100644
--- a/src/test/ui/suggestions/enum-method-probe.rs
+++ b/src/test/ui/suggestions/enum-method-probe.rs
@@ -1,4 +1,6 @@
+// compile-flags: --edition=2021
 // run-rustfix
+
 #![allow(unused)]
 
 struct Foo;
@@ -17,11 +19,26 @@ fn test_result_in_result() -> Result<(), ()> {
     Ok(())
 }
 
-fn test_result_in_plain() {
+async fn async_test_result_in_result() -> Result<(), ()> {
+    let res: Result<_, ()> = Ok(Foo);
+    res.get();
+    //~^ ERROR no method named `get` found for enum `Result` in the current scope
+    //~| HELP use the `?` operator
+    Ok(())
+}
+
+fn test_result_in_unit_return() {
+    let res: Result<_, ()> = Ok(Foo);
+    res.get();
+    //~^ ERROR no method named `get` found for enum `Result` in the current scope
+    //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
+}
+
+async fn async_test_result_in_unit_return() {
     let res: Result<_, ()> = Ok(Foo);
     res.get();
     //~^ ERROR no method named `get` found for enum `Result` in the current scope
-    //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is an `Err`
+    //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
 }
 
 fn test_option_in_option() -> Option<()> {
@@ -32,11 +49,11 @@ fn test_option_in_option() -> Option<()> {
     Some(())
 }
 
-fn test_option_in_plain() {
+fn test_option_in_unit_return() {
     let res: Option<_> = Some(Foo);
     res.get();
     //~^ ERROR no method named `get` found for enum `Option` in the current scope
-    //~| HELP consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is `None`
+    //~| HELP consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is an `Option::None`
 }
 
 fn main() {}
diff --git a/src/test/ui/suggestions/enum-method-probe.stderr b/src/test/ui/suggestions/enum-method-probe.stderr
index 4af1775f66b..6ed14984f47 100644
--- a/src/test/ui/suggestions/enum-method-probe.stderr
+++ b/src/test/ui/suggestions/enum-method-probe.stderr
@@ -1,11 +1,11 @@
 error[E0599]: no method named `get` found for enum `Result` in the current scope
-  --> $DIR/enum-method-probe.rs:14:9
+  --> $DIR/enum-method-probe.rs:24:9
    |
 LL |     res.get();
    |         ^^^ method not found in `Result<Foo, ()>`
    |
 note: the method `get` exists on the type `Foo`
-  --> $DIR/enum-method-probe.rs:7:5
+  --> $DIR/enum-method-probe.rs:9:5
    |
 LL |     fn get(&self) -> u8 {
    |     ^^^^^^^^^^^^^^^^^^^
@@ -15,53 +15,85 @@ LL |     res?.get();
    |        +
 
 error[E0599]: no method named `get` found for enum `Result` in the current scope
-  --> $DIR/enum-method-probe.rs:22:9
+  --> $DIR/enum-method-probe.rs:39:9
    |
 LL |     res.get();
    |         ^^^ method not found in `Result<Foo, ()>`
    |
 note: the method `get` exists on the type `Foo`
-  --> $DIR/enum-method-probe.rs:7:5
+  --> $DIR/enum-method-probe.rs:9:5
    |
 LL |     fn get(&self) -> u8 {
    |     ^^^^^^^^^^^^^^^^^^^
-help: consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is an `Err`
+help: consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
+   |
+LL |     res.expect("REASON").get();
+   |        +++++++++++++++++
+
+error[E0599]: no method named `get` found for enum `Result` in the current scope
+  --> $DIR/enum-method-probe.rs:16:9
+   |
+LL |     res.get();
+   |         ^^^ method not found in `Result<Foo, ()>`
+   |
+note: the method `get` exists on the type `Foo`
+  --> $DIR/enum-method-probe.rs:9:5
+   |
+LL |     fn get(&self) -> u8 {
+   |     ^^^^^^^^^^^^^^^^^^^
+help: use the `?` operator to extract the `Foo` value, propagating a `Result::Err` value to the caller
+   |
+LL |     res?.get();
+   |        +
+
+error[E0599]: no method named `get` found for enum `Result` in the current scope
+  --> $DIR/enum-method-probe.rs:32:9
+   |
+LL |     res.get();
+   |         ^^^ method not found in `Result<Foo, ()>`
+   |
+note: the method `get` exists on the type `Foo`
+  --> $DIR/enum-method-probe.rs:9:5
+   |
+LL |     fn get(&self) -> u8 {
+   |     ^^^^^^^^^^^^^^^^^^^
+help: consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
    |
 LL |     res.expect("REASON").get();
    |        +++++++++++++++++
 
 error[E0599]: no method named `get` found for enum `Option` in the current scope
-  --> $DIR/enum-method-probe.rs:29:9
+  --> $DIR/enum-method-probe.rs:46:9
    |
 LL |     res.get();
    |         ^^^ method not found in `Option<Foo>`
    |
 note: the method `get` exists on the type `Foo`
-  --> $DIR/enum-method-probe.rs:7:5
+  --> $DIR/enum-method-probe.rs:9:5
    |
 LL |     fn get(&self) -> u8 {
    |     ^^^^^^^^^^^^^^^^^^^
-help: use the `?` operator to extract the `Foo` value, propagating a `None` to the caller
+help: use the `?` operator to extract the `Foo` value, propagating an `Option::None` value to the caller
    |
 LL |     res?.get();
    |        +
 
 error[E0599]: no method named `get` found for enum `Option` in the current scope
-  --> $DIR/enum-method-probe.rs:37:9
+  --> $DIR/enum-method-probe.rs:54:9
    |
 LL |     res.get();
    |         ^^^ method not found in `Option<Foo>`
    |
 note: the method `get` exists on the type `Foo`
-  --> $DIR/enum-method-probe.rs:7:5
+  --> $DIR/enum-method-probe.rs:9:5
    |
 LL |     fn get(&self) -> u8 {
    |     ^^^^^^^^^^^^^^^^^^^
-help: consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is `None`
+help: consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is an `Option::None`
    |
 LL |     res.expect("REASON").get();
    |        +++++++++++++++++
 
-error: aborting due to 4 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0599`.