Skip to content

Commit 9f6104c

Browse files
committed
Move check to end of function to filter out methods with better context errors
1 parent 7c95e2c commit 9f6104c

File tree

5 files changed

+35
-43
lines changed

5 files changed

+35
-43
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -470,36 +470,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
470470
);
471471
}
472472

473-
// Check if any of the candidates match
474-
if let Mode::MethodCall = mode && let SelfSource::MethodCall(mut rcvr_expr) = source {
475-
while let hir::ExprKind::MethodCall(_path_segment, parent_expr, _args, method_span) =
476-
rcvr_expr.kind
477-
{
478-
if let hir::ExprKind::MethodCall(.. ) = parent_expr.kind {
479-
} else {
480-
break;
481-
}
482-
let prev_ty = self.resolve_vars_if_possible(
483-
self.typeck_results
484-
.borrow()
485-
.expr_ty_adjusted_opt(parent_expr)
486-
.unwrap_or(Ty::new_misc_error(self.tcx)),);
487-
488-
for _matched_method in self.probe_for_name_many(
489-
Mode::MethodCall,
490-
item_name,
491-
None,
492-
IsSuggestion(true),
493-
prev_ty,
494-
rcvr_expr.hir_id,
495-
ProbeScope::TraitsInScope,) {
496-
err.span_label(method_span, format!("{item_kind} `{item_name}` is available on `{prev_ty}`"));
497-
}
498-
rcvr_expr = parent_expr;
499-
500-
}
501-
}
502-
473+
let mut internal_mutation_in_method = false;
503474
if let SelfSource::MethodCall(rcvr_expr) = source {
504475
self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| {
505476
let call_expr =
@@ -513,7 +484,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
513484
);
514485
probe.is_ok()
515486
});
516-
487+
internal_mutation_in_method = true;
517488
self.note_internal_mutation_in_method(
518489
&mut err,
519490
rcvr_expr,
@@ -1271,6 +1242,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12711242
}
12721243
}
12731244

1245+
// Only if an appropriate error source is not found, check method chain for possible candiates
1246+
let error_source_not_found = unsatisfied_predicates.is_empty() && !internal_mutation_in_method;
1247+
if error_source_not_found && let Mode::MethodCall = mode && let SelfSource::MethodCall(mut rcvr_expr) = source {
1248+
while let hir::ExprKind::MethodCall(_path_segment, parent_expr, _args, method_span) =
1249+
rcvr_expr.kind
1250+
{
1251+
print!("rcvr_expr {:?}", rcvr_expr);
1252+
let prev_ty = self.resolve_vars_if_possible(
1253+
self.typeck_results
1254+
.borrow()
1255+
.expr_ty_adjusted_opt(parent_expr)
1256+
.unwrap_or(Ty::new_misc_error(self.tcx)),);
1257+
1258+
for _matched_method in self.probe_for_name_many(
1259+
Mode::MethodCall,
1260+
item_name,
1261+
None,
1262+
IsSuggestion(true),
1263+
prev_ty,
1264+
rcvr_expr.hir_id,
1265+
ProbeScope::AllTraits,) {
1266+
err.span_label(method_span, format!("{item_kind} `{item_name}` is available on `{prev_ty}`"));
1267+
}
1268+
rcvr_expr = parent_expr;
1269+
1270+
}
1271+
}
12741272
self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
12751273
return Some(err);
12761274
}

tests/ui/mismatched_types/issue-36053-2.stderr

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@ error[E0599]: the method `count` exists for struct `Filter<Fuse<Once<&str>>, {cl
1919
--> $DIR/issue-36053-2.rs:7:55
2020
|
2121
LL | once::<&str>("str").fuse().filter(|a: &str| true).count();
22-
| ---------------------- ^^^^^ method cannot be called due to unsatisfied trait bounds
23-
| | |
24-
| | doesn't satisfy `<_ as FnOnce<(&&str,)>>::Output = bool`
25-
| | doesn't satisfy `_: FnMut<(&&str,)>`
26-
| method `count` is available on `Fuse<std::iter::Once<&str>>`
22+
| --------- ^^^^^ method cannot be called due to unsatisfied trait bounds
23+
| |
24+
| doesn't satisfy `<_ as FnOnce<(&&str,)>>::Output = bool`
25+
| doesn't satisfy `_: FnMut<(&&str,)>`
2726
--> $SRC_DIR/core/src/iter/adapters/filter.rs:LL:COL
2827
|
2928
= note: doesn't satisfy `_: Iterator`

tests/ui/structs/method-chain-expression-failure.stderr

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ LL | struct D;
55
| -------- method `foo` not found for this struct
66
...
77
LL | A.b().c().d().foo();
8-
| --- ^^^ method not found in `D`
9-
| |
10-
| method `foo` is available on `&B`
8+
| ^^^ method not found in `D`
119

1210
error: aborting due to previous error
1311

tests/ui/suggestions/chain-method-call-mutation-in-place.stderr

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ error[E0599]: no method named `sort` found for unit type `()` in the current sco
1818
--> $DIR/chain-method-call-mutation-in-place.rs:3:72
1919
|
2020
LL | vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i).sort();
21-
| ------------------ ^^^^ method not found in `()`
22-
| |
23-
| method `sort` is available on `&mut [i32]`
21+
| ^^^^ method not found in `()`
2422
|
2523
note: method `sort_by_key` modifies its receiver in-place, it is not meant to be used in method chains.
2624
--> $DIR/chain-method-call-mutation-in-place.rs:3:53

tests/ui/typeck/issue-31173.stderr

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ LL | | found_e = true;
3131
LL | | false
3232
LL | | })
3333
LL | | .cloned()
34-
| | -------- method `collect` is available on `TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>`
3534
LL | | .collect();
3635
| | -^^^^^^^ method cannot be called due to unsatisfied trait bounds
3736
| |_________|

0 commit comments

Comments
 (0)