Skip to content

Commit 3907877

Browse files
authored
Unrolled build for rust-lang#125080
Rollup merge of rust-lang#125080 - bvanjoi:fix-124946, r=nnethercote only find segs chain for missing methods when no available candidates Fixes rust-lang#124946 This PR includes two changes: - Extracting the lookup for the missing method in chains into a single function. - Calling this function only when there are no candidates available.
2 parents bdfd941 + ade33b0 commit 3907877

File tree

3 files changed

+67
-6
lines changed

3 files changed

+67
-6
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

+33-6
Original file line numberDiff line numberDiff line change
@@ -1143,7 +1143,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11431143
}
11441144
}
11451145

1146-
let label_span_not_found = |err: &mut Diag<'_>| {
1146+
let mut find_candidate_for_method = false;
1147+
1148+
let mut label_span_not_found = |err: &mut Diag<'_>| {
11471149
if unsatisfied_predicates.is_empty() {
11481150
err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
11491151
let is_string_or_ref_str = match rcvr_ty.kind() {
@@ -1219,6 +1221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12191221
err.note(format!(
12201222
"the {item_kind} was found for\n{type_candidates}{additional_types}"
12211223
));
1224+
find_candidate_for_method = mode == Mode::MethodCall;
12221225
}
12231226
}
12241227
} else {
@@ -1371,9 +1374,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13711374
);
13721375
}
13731376
}
1374-
// If an appropriate error source is not found, check method chain for possible candiates
1375-
if unsatisfied_predicates.is_empty()
1376-
&& let Mode::MethodCall = mode
1377+
1378+
if !find_candidate_for_method {
1379+
self.lookup_segments_chain_for_no_match_method(
1380+
&mut err,
1381+
item_name,
1382+
item_kind,
1383+
source,
1384+
no_match_data,
1385+
);
1386+
}
1387+
1388+
self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
1389+
Some(err)
1390+
}
1391+
1392+
/// If an appropriate error source is not found, check method chain for possible candidates
1393+
fn lookup_segments_chain_for_no_match_method(
1394+
&self,
1395+
err: &mut Diag<'_>,
1396+
item_name: Ident,
1397+
item_kind: &str,
1398+
source: SelfSource<'tcx>,
1399+
no_match_data: &NoMatchData<'tcx>,
1400+
) {
1401+
if no_match_data.unsatisfied_predicates.is_empty()
1402+
&& let Mode::MethodCall = no_match_data.mode
13771403
&& let SelfSource::MethodCall(mut source_expr) = source
13781404
{
13791405
let mut stack_methods = vec![];
@@ -1394,6 +1420,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13941420
.unwrap_or(Ty::new_misc_error(self.tcx)),
13951421
);
13961422

1423+
// FIXME: `probe_for_name_many` searches for methods in inherent implementations,
1424+
// so it may return a candidate that doesn't belong to this `revr_ty`. We need to
1425+
// check whether the instantiated type matches the received one.
13971426
for _matched_method in self.probe_for_name_many(
13981427
Mode::MethodCall,
13991428
item_name,
@@ -1416,8 +1445,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14161445
);
14171446
}
14181447
}
1419-
self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
1420-
Some(err)
14211448
}
14221449

14231450
fn find_likely_intended_associated_item(
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// https://github.com/rust-lang/rust/issues/124946
2+
3+
struct Builder<const A: bool, const B: bool>;
4+
5+
impl<const A: bool> Builder<A, false> {
6+
fn cast(self) -> Builder<A, true> {
7+
Builder
8+
}
9+
}
10+
11+
impl Builder<true, true> {
12+
fn build(self) {}
13+
}
14+
15+
fn main() {
16+
let b = Builder::<false, false>;
17+
b.cast().build();
18+
//~^ ERROR: no method named `build` found for struct `Builder<false, true>` in the current scope
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0599]: no method named `build` found for struct `Builder<false, true>` in the current scope
2+
--> $DIR/lookup-method.rs:17:14
3+
|
4+
LL | struct Builder<const A: bool, const B: bool>;
5+
| -------------------------------------------- method `build` not found for this struct
6+
...
7+
LL | b.cast().build();
8+
| ^^^^^ method not found in `Builder<false, true>`
9+
|
10+
= note: the method was found for
11+
- `Builder<true, true>`
12+
13+
error: aborting due to 1 previous error
14+
15+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)