about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs14
-rw-r--r--tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs11
-rw-r--r--tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr40
5 files changed, 72 insertions, 11 deletions
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 5d30b2a71e0..d2a5924c8bb 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -827,7 +827,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         ) else {
             return;
         };
-        let in_scope_methods = self.probe_for_name_many(
+
+        let Ok(in_scope_methods) = self.probe_for_name_many(
             probe::Mode::MethodCall,
             path.ident,
             Some(expected),
@@ -835,11 +836,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self_ty,
             deref.hir_id,
             probe::ProbeScope::TraitsInScope,
-        );
+        ) else {
+            return;
+        };
+
         let other_methods_in_scope: Vec<_> =
             in_scope_methods.iter().filter(|c| c.item.def_id != pick.item.def_id).collect();
 
-        let all_methods = self.probe_for_name_many(
+        let Ok(all_methods) = self.probe_for_name_many(
             probe::Mode::MethodCall,
             path.ident,
             Some(expected),
@@ -847,7 +851,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self_ty,
             deref.hir_id,
             probe::ProbeScope::AllTraits,
-        );
+        ) else {
+            return;
+        };
+
         let suggestions: Vec<_> = all_methods
             .into_iter()
             .filter(|c| c.item.def_id != pick.item.def_id)
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index ab0f16bd87d..e842bba34bf 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -306,7 +306,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self_ty: Ty<'tcx>,
         scope_expr_id: HirId,
         scope: ProbeScope,
-    ) -> Vec<Candidate<'tcx>> {
+    ) -> Result<Vec<Candidate<'tcx>>, MethodError<'tcx>> {
         self.probe_op(
             item_name.span,
             mode,
@@ -324,7 +324,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .collect())
             },
         )
-        .unwrap()
     }
 
     pub(crate) fn probe_op<OP, R>(
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index c1e14f7fb75..bbe4a8791c6 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1640,10 +1640,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         .unwrap_or(Ty::new_misc_error(self.tcx)),
                 );
 
-                // FIXME: `probe_for_name_many` searches for methods in inherent implementations,
-                // so it may return a candidate that doesn't belong to this `revr_ty`. We need to
-                // check whether the instantiated type matches the received one.
-                for _matched_method in self.probe_for_name_many(
+                let Ok(candidates) = self.probe_for_name_many(
                     Mode::MethodCall,
                     item_name,
                     None,
@@ -1651,7 +1648,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     rcvr_ty,
                     source_expr.hir_id,
                     ProbeScope::TraitsInScope,
-                ) {
+                ) else {
+                    return;
+                };
+
+                // FIXME: `probe_for_name_many` searches for methods in inherent implementations,
+                // so it may return a candidate that doesn't belong to this `revr_ty`. We need to
+                // check whether the instantiated type matches the received one.
+                for _matched_method in candidates {
                     // found a match, push to stack
                     stack_methods.push(rcvr_ty);
                 }
diff --git a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs
new file mode 100644
index 00000000000..efa296db47c
--- /dev/null
+++ b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs
@@ -0,0 +1,11 @@
+// Regression test for ICE #125876
+
+fn main() {
+    std::ptr::from_ref(num).cast_mut().as_deref();
+    //~^ ERROR cannot find value `num` in this scope
+    //~| ERROR no method named `as_deref` found for raw pointer `*mut _` in the current scope
+    //~| WARN type annotations needed
+    //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+    //~| WARN type annotations needed
+    //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+}
diff --git a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr
new file mode 100644
index 00000000000..d610a3b7cad
--- /dev/null
+++ b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr
@@ -0,0 +1,40 @@
+error[E0425]: cannot find value `num` in this scope
+  --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:24
+   |
+LL |     std::ptr::from_ref(num).cast_mut().as_deref();
+   |                        ^^^ not found in this scope
+
+warning: type annotations needed
+  --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:29
+   |
+LL |     std::ptr::from_ref(num).cast_mut().as_deref();
+   |                             ^^^^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906>
+   = note: `#[warn(tyvar_behind_raw_pointer)]` on by default
+
+warning: type annotations needed
+  --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:40
+   |
+LL |     std::ptr::from_ref(num).cast_mut().as_deref();
+   |                                        ^^^^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906>
+
+error[E0599]: no method named `as_deref` found for raw pointer `*mut _` in the current scope
+  --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:40
+   |
+LL |     std::ptr::from_ref(num).cast_mut().as_deref();
+   |                                        ^^^^^^^^
+   |
+help: there is a method `as_ref` with a similar name
+   |
+LL |     std::ptr::from_ref(num).cast_mut().as_ref();
+   |                                        ~~~~~~
+
+error: aborting due to 2 previous errors; 2 warnings emitted
+
+Some errors have detailed explanations: E0425, E0599.
+For more information about an error, try `rustc --explain E0425`.