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> { + ) -> Result>, 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( 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 + = 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 + +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`.