Skip to content

Commit

Permalink
Fix ICE due to unwrap in probe_for_name_many
Browse files Browse the repository at this point in the history
  • Loading branch information
gurry committed Jun 7, 2024
1 parent 76e7a08 commit 048a42d
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 29 deletions.
42 changes: 24 additions & 18 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -827,27 +827,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) else {
return;
};
let in_scope_methods = self.probe_for_name_many(
probe::Mode::MethodCall,
path.ident,
Some(expected),
probe::IsSuggestion(true),
self_ty,
deref.hir_id,
probe::ProbeScope::TraitsInScope,
);
let in_scope_methods = self
.probe_for_name_many(
probe::Mode::MethodCall,
path.ident,
Some(expected),
probe::IsSuggestion(true),
self_ty,
deref.hir_id,
probe::ProbeScope::TraitsInScope,
)
.unwrap_or(Vec::new());

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(
probe::Mode::MethodCall,
path.ident,
Some(expected),
probe::IsSuggestion(true),
self_ty,
deref.hir_id,
probe::ProbeScope::AllTraits,
);
let all_methods = self
.probe_for_name_many(
probe::Mode::MethodCall,
path.ident,
Some(expected),
probe::IsSuggestion(true),
self_ty,
deref.hir_id,
probe::ProbeScope::AllTraits,
)
.unwrap_or(Vec::new());

let suggestions: Vec<_> = all_methods
.into_iter()
.filter(|c| c.item.def_id != pick.item.def_id)
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -324,7 +324,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.collect())
},
)
.unwrap()
}

pub(crate) fn probe_op<OP, R>(
Expand Down
22 changes: 13 additions & 9 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1640,18 +1640,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.unwrap_or(Ty::new_misc_error(self.tcx)),
);

let candidates = self
.probe_for_name_many(
Mode::MethodCall,
item_name,
None,
IsSuggestion(true),
rcvr_ty,
source_expr.hir_id,
ProbeScope::TraitsInScope,
)
.unwrap_or(Vec::new());

// 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(
Mode::MethodCall,
item_name,
None,
IsSuggestion(true),
rcvr_ty,
source_expr.hir_id,
ProbeScope::TraitsInScope,
) {
for _matched_method in candidates {
// found a match, push to stack
stack_methods.push(rcvr_ty);
}
Expand Down
11 changes: 11 additions & 0 deletions tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs
Original file line number Diff line number Diff line change
@@ -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!
}
40 changes: 40 additions & 0 deletions tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 048a42d

Please sign in to comment.