Skip to content

Commit d59f430

Browse files
Rollup merge of #125100 - compiler-errors:faster, r=nnethercote
Don't do post-method-probe error reporting steps if we're in a suggestion Currently in method probing, if we fail to pick a method, then we reset and try to collect relevant candidates for method errors: https://github.com/rust-lang/rust/blob/34582118afaf00b0eb2d209a90b181c7156b501c/compiler/rustc_hir_typeck/src/method/probe.rs#L953-L993 However, we do method lookups via `lookup_method_for_diagnostic` and only care about the result if the method probe was a *success*. Namely, we don't need to do a bunch of other lookups on failure, since we throw away these results anyways, such as an expensive call to: https://github.com/rust-lang/rust/blob/34582118afaf00b0eb2d209a90b181c7156b501c/compiler/rustc_hir_typeck/src/method/probe.rs#L959 And: https://github.com/rust-lang/rust/blob/34582118afaf00b0eb2d209a90b181c7156b501c/compiler/rustc_hir_typeck/src/method/probe.rs#L985 --- This PR also renames some methods so it's clear that they're for diagnostics. r? `@nnethercote`
2 parents 712e7c3 + 8f97a25 commit d59f430

File tree

8 files changed

+284
-9
lines changed

8 files changed

+284
-9
lines changed

compiler/rustc_hir_typeck/src/demand.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -938,14 +938,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
938938
);
939939
}
940940

941-
pub fn get_conversion_methods(
941+
pub fn get_conversion_methods_for_diagnostic(
942942
&self,
943943
span: Span,
944944
expected: Ty<'tcx>,
945945
checked_ty: Ty<'tcx>,
946946
hir_id: hir::HirId,
947947
) -> Vec<AssocItem> {
948-
let methods = self.probe_for_return_type(
948+
let methods = self.probe_for_return_type_for_diagnostic(
949949
span,
950950
probe::Mode::MethodCall,
951951
expected,

compiler/rustc_hir_typeck/src/expr.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -2414,7 +2414,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24142414

24152415
let guar = if field.name == kw::Empty {
24162416
self.dcx().span_delayed_bug(field.span, "field name with no name")
2417-
} else if self.method_exists(field, base_ty, expr.hir_id, expected.only_has_type(self)) {
2417+
} else if self.method_exists_for_diagnostic(
2418+
field,
2419+
base_ty,
2420+
expr.hir_id,
2421+
expected.only_has_type(self),
2422+
) {
24182423
self.ban_take_value_of_method(expr, base_ty, field)
24192424
} else if !base_ty.is_primitive_ty() {
24202425
self.ban_nonexisting_field(field, base, expr, base_ty)
@@ -2600,7 +2605,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26002605
let mut err = self.private_field_err(field, base_did);
26012606

26022607
// Also check if an accessible method exists, which is often what is meant.
2603-
if self.method_exists(field, expr_t, expr.hir_id, return_ty)
2608+
if self.method_exists_for_diagnostic(field, expr_t, expr.hir_id, return_ty)
26042609
&& !self.expr_in_place(expr.hir_id)
26052610
{
26062611
self.suggest_method_call(

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
290290
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
291291
) -> bool {
292292
let expr = expr.peel_blocks();
293-
let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
293+
let methods =
294+
self.get_conversion_methods_for_diagnostic(expr.span, expected, found, expr.hir_id);
294295

295296
if let Some((suggestion, msg, applicability, verbose, annotation)) =
296297
self.suggest_deref_or_ref(expr, found, expected)

compiler/rustc_hir_typeck/src/method/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub enum CandidateSource {
9191
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9292
/// Determines whether the type `self_ty` supports a visible method named `method_name` or not.
9393
#[instrument(level = "debug", skip(self))]
94-
pub fn method_exists(
94+
pub fn method_exists_for_diagnostic(
9595
&self,
9696
method_name: Ident,
9797
self_ty: Ty<'tcx>,
@@ -102,7 +102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
102102
probe::Mode::MethodCall,
103103
method_name,
104104
return_type,
105-
IsSuggestion(false),
105+
IsSuggestion(true),
106106
self_ty,
107107
call_expr_id,
108108
ProbeScope::TraitsInScope,

compiler/rustc_hir_typeck/src/method/probe.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ pub(crate) struct ProbeContext<'a, 'tcx> {
9090
>,
9191

9292
scope_expr_id: HirId,
93+
94+
/// Is this probe being done for a diagnostic? This will skip some error reporting
95+
/// machinery, since we don't particularly care about, for example, similarly named
96+
/// candidates if we're *reporting* similarly named candidates.
97+
is_suggestion: IsSuggestion,
9398
}
9499

95100
impl<'a, 'tcx> Deref for ProbeContext<'a, 'tcx> {
@@ -220,7 +225,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
220225
/// would use to decide if a method is a plausible fit for
221226
/// ambiguity purposes).
222227
#[instrument(level = "debug", skip(self, candidate_filter))]
223-
pub fn probe_for_return_type(
228+
pub fn probe_for_return_type_for_diagnostic(
224229
&self,
225230
span: Span,
226231
mode: Mode,
@@ -459,6 +464,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
459464
&orig_values,
460465
steps.steps,
461466
scope_expr_id,
467+
is_suggestion,
462468
);
463469

464470
probe_cx.assemble_inherent_candidates();
@@ -553,6 +559,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
553559
orig_steps_var_values: &'a OriginalQueryValues<'tcx>,
554560
steps: &'tcx [CandidateStep<'tcx>],
555561
scope_expr_id: HirId,
562+
is_suggestion: IsSuggestion,
556563
) -> ProbeContext<'a, 'tcx> {
557564
ProbeContext {
558565
fcx,
@@ -570,6 +577,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
570577
static_candidates: RefCell::new(Vec::new()),
571578
unsatisfied_predicates: RefCell::new(Vec::new()),
572579
scope_expr_id,
580+
is_suggestion,
573581
}
574582
}
575583

@@ -944,6 +952,18 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
944952
return r;
945953
}
946954

955+
// If it's a `lookup_probe_for_diagnostic`, then quit early. No need to
956+
// probe for other candidates.
957+
if self.is_suggestion.0 {
958+
return Err(MethodError::NoMatch(NoMatchData {
959+
static_candidates: vec![],
960+
unsatisfied_predicates: vec![],
961+
out_of_scope_traits: vec![],
962+
similar_candidate: None,
963+
mode: self.mode,
964+
}));
965+
}
966+
947967
debug!("pick: actual search failed, assemble diagnostics");
948968

949969
let static_candidates = std::mem::take(self.static_candidates.get_mut());
@@ -1631,6 +1651,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16311651
self.orig_steps_var_values,
16321652
self.steps,
16331653
self.scope_expr_id,
1654+
IsSuggestion(true),
16341655
);
16351656
pcx.allow_similar_names = true;
16361657
pcx.assemble_inherent_candidates();

compiler/rustc_hir_typeck/src/method/suggest.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2841,7 +2841,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28412841
Some(output_ty) => self.resolve_vars_if_possible(output_ty),
28422842
_ => return,
28432843
};
2844-
let method_exists = self.method_exists(item_name, output_ty, call.hir_id, return_type);
2844+
let method_exists =
2845+
self.method_exists_for_diagnostic(item_name, output_ty, call.hir_id, return_type);
28452846
debug!("suggest_await_before_method: is_method_exist={}", method_exists);
28462847
if method_exists {
28472848
err.span_suggestion_verbose(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#![allow(non_snake_case)]
2+
3+
// Ensures that we don't spend an unnecessary amount of compiler time building
4+
// suggestions for mistyped methods. This used to happen because when we had method
5+
// lookup failures, we would do subsequent method lookups, and those would themselves
6+
// do extra work that was unnecessary for the purposes of suggestions.
7+
// Fixed by #125100.
8+
9+
macro_rules! traits {
10+
($($name:ident),*) => {
11+
$(
12+
trait $name {
13+
fn $name(&self);
14+
}
15+
)*
16+
}
17+
}
18+
19+
traits!(
20+
A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20,
21+
A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36, A37, A38, A39,
22+
A40, A41, A42, A43, A44, A45, A46, A47, A48, A49, A50, A51, A52, A53, A54, A55, A56, A57, A58,
23+
A59, A60, A61, A62, A63, A64, A65, A66, A67, A68, A69, A70, A71, A72, A73, A74, A75, A76, A77,
24+
A78, A79, A80, A81, A82, A83, A84, A85, A86, A87, A88, A89, A90, A91, A92, A93, A94, A95, A96,
25+
A97, A98, A99, A100, A101, A102, A103, A104, A105, A106, A107, A108, A109, A110, A111, A112,
26+
A113, A114, A115, A116, A117, A118, A119, A120, A121, A122, A123, A124, A125, A126, A127, A128,
27+
A129, A130, A131, A132, A133, A134, A135, A136, A137, A138, A139, A140, A141, A142, A143, A144,
28+
A145, A146, A147, A148, A149, A150, A151, A152, A153, A154, A155, A156, A157, A158, A159, A160,
29+
A161, A162, A163, A164, A165, A166, A167, A168, A169, A170, A171, A172, A173, A174, A175, A176,
30+
A177, A178, A179, A180, A181, A182, A183, A184, A185, A186, A187, A188, A189, A190, A191, A192,
31+
A193, A194, A195, A196, A197, A198, A199, A200, A201, A202, A203, A204, A205, A206, A207, A208,
32+
A209, A210, A211, A212, A213, A214, A215, A216, A217, A218, A219, A220, A221, A222, A223, A224,
33+
A225, A226, A227, A228, A229, A230, A231, A232, A233, A234, A235, A236, A237, A238, A239, A240,
34+
A241, A242, A243, A244, A245, A246, A247, A248, A249, A250, A251, A252, A253, A254, A255, A256,
35+
A257, A258, A259, A260, A261, A262, A263, A264, A265, A266, A267, A268, A269, A270, A271, A272,
36+
A273, A274, A275, A276, A277, A278, A279, A280, A281, A282, A283, A284, A285, A286, A287, A288,
37+
A289, A290, A291, A292, A293, A294, A295, A296, A297, A298, A299, A300, A301, A302, A303, A304,
38+
A305, A306, A307, A308, A309, A310, A311, A312, A313, A314, A315, A316, A317, A318, A319, A320,
39+
A321, A322, A323, A324, A325, A326, A327, A328, A329, A330, A331, A332, A333, A334, A335, A336,
40+
A337, A338, A339, A340, A341, A342, A343, A344, A345, A346, A347, A348, A349, A350, A351, A352,
41+
A353, A354, A355, A356, A357, A358, A359, A360, A361, A362, A363, A364, A365, A366, A367, A368,
42+
A369, A370, A371, A372, A373, A374, A375, A376, A377, A378, A379, A380, A381, A382, A383, A384,
43+
A385, A386, A387, A388, A389, A390, A391, A392, A393, A394, A395, A396, A397, A398, A399, A400,
44+
A401, A402, A403, A404, A405, A406, A407, A408, A409, A410, A411, A412, A413, A414, A415, A416,
45+
A417, A418, A419, A420, A421, A422, A423, A424, A425, A426, A427, A428, A429, A430, A431, A432,
46+
A433, A434, A435, A436, A437, A438, A439, A440, A441, A442, A443, A444, A445, A446, A447, A448,
47+
A449, A450, A451, A452, A453, A454, A455, A456, A457, A458, A459, A460, A461, A462, A463, A464,
48+
A465, A466, A467, A468, A469, A470, A471, A472, A473, A474, A475, A476, A477, A478, A479, A480,
49+
A481, A482, A483, A484, A485, A486, A487, A488, A489, A490, A491, A492, A493, A494, A495, A496,
50+
A497, A498, A499, A500, A501, A502, A503, A504, A505, A506, A507, A508, A509, A510, A511, A512,
51+
A513, A514, A515, A516, A517, A518, A519, A520, A521, A522, A523, A524, A525, A526, A527, A528,
52+
A529, A530, A531, A532, A533, A534, A535, A536, A537, A538, A539, A540, A541, A542, A543, A544,
53+
A545, A546, A547, A548, A549, A550, A551, A552, A553, A554, A555, A556, A557, A558, A559, A560,
54+
A561, A562, A563, A564, A565, A566, A567, A568, A569, A570, A571, A572, A573, A574, A575, A576,
55+
A577, A578, A579, A580, A581, A582, A583, A584, A585, A586, A587, A588, A589, A590, A591, A592,
56+
A593, A594, A595, A596, A597, A598, A599, A600, A601, A602, A603, A604, A605, A606, A607, A608,
57+
A609, A610, A611, A612, A613, A614, A615, A616, A617, A618, A619, A620, A621, A622, A623, A624,
58+
A625, A626, A627, A628, A629, A630, A631, A632, A633, A634, A635, A636, A637, A638, A639, A640,
59+
A641, A642, A643, A644, A645, A646, A647, A648, A649, A650, A651, A652, A653, A654, A655, A656,
60+
A657, A658, A659, A660, A661, A662, A663, A664, A665, A666, A667, A668, A669, A670, A671, A672,
61+
A673, A674, A675, A676, A677, A678, A679, A680, A681, A682, A683, A684, A685, A686, A687, A688,
62+
A689, A690, A691, A692, A693, A694, A695, A696, A697, A698, A699, A700, A701, A702, A703, A704,
63+
A705, A706, A707, A708, A709, A710, A711, A712, A713, A714, A715, A716, A717, A718, A719, A720,
64+
A721, A722, A723, A724, A725, A726, A727, A728, A729, A730, A731, A732, A733, A734, A735, A736,
65+
A737, A738, A739, A740, A741, A742, A743, A744, A745, A746, A747, A748, A749, A750, A751, A752,
66+
A753, A754, A755, A756, A757, A758, A759, A760, A761, A762, A763, A764, A765, A766, A767, A768,
67+
A769, A770, A771, A772, A773, A774, A775, A776, A777, A778, A779, A780, A781, A782, A783, A784,
68+
A785, A786, A787, A788, A789, A790, A791, A792, A793, A794, A795, A796, A797, A798, A799, A800,
69+
A801, A802, A803, A804, A805, A806, A807, A808, A809, A810, A811, A812, A813, A814, A815, A816,
70+
A817, A818, A819, A820, A821, A822, A823, A824, A825, A826, A827, A828, A829, A830, A831, A832,
71+
A833, A834, A835, A836, A837, A838, A839, A840, A841, A842, A843, A844, A845, A846, A847, A848,
72+
A849, A850, A851, A852, A853, A854, A855, A856, A857, A858, A859, A860, A861, A862, A863, A864,
73+
A865, A866, A867, A868, A869, A870, A871, A872, A873, A874, A875, A876, A877, A878, A879, A880,
74+
A881, A882, A883, A884, A885, A886, A887, A888, A889, A890, A891, A892, A893, A894, A895, A896,
75+
A897, A898, A899, A900, A901, A902, A903, A904, A905, A906, A907, A908, A909, A910, A911, A912,
76+
A913, A914, A915, A916, A917, A918, A919, A920, A921, A922, A923, A924, A925, A926, A927, A928,
77+
A929, A930, A931, A932, A933, A934, A935, A936, A937, A938, A939, A940, A941, A942, A943, A944,
78+
A945, A946, A947, A948, A949, A950, A951, A952, A953, A954, A955, A956, A957, A958, A959, A960,
79+
A961, A962, A963, A964, A965, A966, A967, A968, A969, A970, A971, A972, A973, A974, A975, A976,
80+
A977, A978, A979, A980, A981, A982, A983, A984, A985, A986, A987, A988, A989, A990, A991, A992,
81+
A993, A994, A995, A996, A997, A998, A999
82+
);
83+
84+
#[derive(Default)]
85+
struct M0 {
86+
m1: M1,
87+
m2: M1,
88+
m3: M1,
89+
m4: M1,
90+
m5: M1,
91+
m6: M1,
92+
m7: M1,
93+
m8: M1,
94+
m9: M1,
95+
m10: M1,
96+
m11: M1,
97+
m12: M1,
98+
m13: M1,
99+
m14: M1,
100+
m15: M1,
101+
}
102+
103+
#[derive(Default)]
104+
struct M1 {
105+
m1: M2,
106+
m2: M2,
107+
m3: M2,
108+
m4: M2,
109+
m5: M2,
110+
m6: M2,
111+
m7: M2,
112+
m8: M2,
113+
m9: M2,
114+
m10: M2,
115+
m11: M2,
116+
m12: M2,
117+
m13: M2,
118+
m14: M2,
119+
m15: M2,
120+
}
121+
122+
#[derive(Default)]
123+
struct M2 {
124+
m1: M3,
125+
m2: M3,
126+
m3: M3,
127+
m4: M3,
128+
m5: M3,
129+
m6: M3,
130+
m7: M3,
131+
m8: M3,
132+
m9: M3,
133+
m10: M3,
134+
m11: M3,
135+
m12: M3,
136+
m13: M3,
137+
m14: M3,
138+
m15: M3,
139+
}
140+
141+
#[derive(Default)]
142+
struct M3 {}
143+
144+
fn main() {
145+
M0::default().Au();
146+
//~^ ERROR no method named `Au` found for struct `M0` in the current scope
147+
M0::default().Au();
148+
//~^ ERROR no method named `Au` found for struct `M0` in the current scope
149+
M0::default().Au();
150+
//~^ ERROR no method named `Au` found for struct `M0` in the current scope
151+
M0::default().Au();
152+
//~^ ERROR no method named `Au` found for struct `M0` in the current scope
153+
M0::default().Au();
154+
//~^ ERROR no method named `Au` found for struct `M0` in the current scope
155+
M0::default().Au();
156+
//~^ ERROR no method named `Au` found for struct `M0` in the current scope
157+
M0::default().Au();
158+
//~^ ERROR no method named `Au` found for struct `M0` in the current scope
159+
M0::default().Au();
160+
//~^ ERROR no method named `Au` found for struct `M0` in the current scope
161+
M0::default().Au();
162+
//~^ ERROR no method named `Au` found for struct `M0` in the current scope
163+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
error[E0599]: no method named `Au` found for struct `M0` in the current scope
2+
--> $DIR/probe-for-diagnostic-doesnt-do-extra-work.rs:145:19
3+
|
4+
LL | struct M0 {
5+
| --------- method `Au` not found for this struct
6+
...
7+
LL | M0::default().Au();
8+
| ^^ method not found in `M0`
9+
10+
error[E0599]: no method named `Au` found for struct `M0` in the current scope
11+
--> $DIR/probe-for-diagnostic-doesnt-do-extra-work.rs:147:19
12+
|
13+
LL | struct M0 {
14+
| --------- method `Au` not found for this struct
15+
...
16+
LL | M0::default().Au();
17+
| ^^ method not found in `M0`
18+
19+
error[E0599]: no method named `Au` found for struct `M0` in the current scope
20+
--> $DIR/probe-for-diagnostic-doesnt-do-extra-work.rs:149:19
21+
|
22+
LL | struct M0 {
23+
| --------- method `Au` not found for this struct
24+
...
25+
LL | M0::default().Au();
26+
| ^^ method not found in `M0`
27+
28+
error[E0599]: no method named `Au` found for struct `M0` in the current scope
29+
--> $DIR/probe-for-diagnostic-doesnt-do-extra-work.rs:151:19
30+
|
31+
LL | struct M0 {
32+
| --------- method `Au` not found for this struct
33+
...
34+
LL | M0::default().Au();
35+
| ^^ method not found in `M0`
36+
37+
error[E0599]: no method named `Au` found for struct `M0` in the current scope
38+
--> $DIR/probe-for-diagnostic-doesnt-do-extra-work.rs:153:19
39+
|
40+
LL | struct M0 {
41+
| --------- method `Au` not found for this struct
42+
...
43+
LL | M0::default().Au();
44+
| ^^ method not found in `M0`
45+
46+
error[E0599]: no method named `Au` found for struct `M0` in the current scope
47+
--> $DIR/probe-for-diagnostic-doesnt-do-extra-work.rs:155:19
48+
|
49+
LL | struct M0 {
50+
| --------- method `Au` not found for this struct
51+
...
52+
LL | M0::default().Au();
53+
| ^^ method not found in `M0`
54+
55+
error[E0599]: no method named `Au` found for struct `M0` in the current scope
56+
--> $DIR/probe-for-diagnostic-doesnt-do-extra-work.rs:157:19
57+
|
58+
LL | struct M0 {
59+
| --------- method `Au` not found for this struct
60+
...
61+
LL | M0::default().Au();
62+
| ^^ method not found in `M0`
63+
64+
error[E0599]: no method named `Au` found for struct `M0` in the current scope
65+
--> $DIR/probe-for-diagnostic-doesnt-do-extra-work.rs:159:19
66+
|
67+
LL | struct M0 {
68+
| --------- method `Au` not found for this struct
69+
...
70+
LL | M0::default().Au();
71+
| ^^ method not found in `M0`
72+
73+
error[E0599]: no method named `Au` found for struct `M0` in the current scope
74+
--> $DIR/probe-for-diagnostic-doesnt-do-extra-work.rs:161:19
75+
|
76+
LL | struct M0 {
77+
| --------- method `Au` not found for this struct
78+
...
79+
LL | M0::default().Au();
80+
| ^^ method not found in `M0`
81+
82+
error: aborting due to 9 previous errors
83+
84+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)