Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit bd36e69

Browse filesBrowse files
committed
Auto merge of rust-lang#133566 - lcnr:fast-reject-perf, r=compiler-errors
fast-reject: add cache slightly modified version of rust-lang#133524 I tried a few alternatives: - simply bail after recursion for a certain amount of times, however, looking at the number of steps taken while compiling different crates we get the following results[^1]: - add a cache: results in a bigger performance impact typenum ```rust 1098842 counts ( 1) 670511 (61.0%, 61.0%): dropping after 1 ( 2) 358785 (32.7%, 93.7%): dropping after 0 ( 3) 25191 ( 2.3%, 96.0%): dropping after 2 ( 4) 10912 ( 1.0%, 97.0%): dropping after 4 ( 5) 6461 ( 0.6%, 97.5%): dropping after 3 ( 6) 5239 ( 0.5%, 98.0%): dropping after 5 ( 7) 2528 ( 0.2%, 98.3%): dropping after 8 ( 8) 2188 ( 0.2%, 98.5%): dropping after 1094 ( 9) 2097 ( 0.2%, 98.6%): dropping after 6 ( 10) 1179 ( 0.1%, 98.7%): dropping after 34 ( 11) 1148 ( 0.1%, 98.9%): dropping after 7 ( 12) 822 ( 0.1%, 98.9%): dropping after 10 ``` bitmaps ```rust 533346 counts ( 1) 526166 (98.7%, 98.7%): dropping after 1 ( 2) 4562 ( 0.9%, 99.5%): dropping after 0 ( 3) 2072 ( 0.4%, 99.9%): dropping after 1024 ( 4) 305 ( 0.1%,100.0%): dropping after 2 ( 5) 106 ( 0.0%,100.0%): dropping after 4 ( 6) 30 ( 0.0%,100.0%): dropping after 8 ( 7) 18 ( 0.0%,100.0%): dropping after 3 ( 8) 17 ( 0.0%,100.0%): dropping after 44 ( 9) 15 ( 0.0%,100.0%): dropping after 168 ( 10) 8 ( 0.0%,100.0%): dropping after 14 ( 11) 7 ( 0.0%,100.0%): dropping after 13 ( 12) 7 ( 0.0%,100.0%): dropping after 24 ``` stage 2 compiler is mostly trivial, but has a few cases where we get >5000 ```rust 12987156 counts ( 1) 9280476 (71.5%, 71.5%): dropping after 0 ( 2) 2277841 (17.5%, 89.0%): dropping after 1 ( 3) 724888 ( 5.6%, 94.6%): dropping after 2 ( 4) 204005 ( 1.6%, 96.2%): dropping after 4 ( 5) 146537 ( 1.1%, 97.3%): dropping after 3 ( 6) 64287 ( 0.5%, 97.8%): dropping after 5 ( 7) 43938 ( 0.3%, 98.1%): dropping after 6 ( 8) 43758 ( 0.3%, 98.4%): dropping after 8 ( 9) 27220 ( 0.2%, 98.7%): dropping after 7 ( 10) 17374 ( 0.1%, 98.8%): dropping after 9 ( 11) 16015 ( 0.1%, 98.9%): dropping after 10 ( 12) 12855 ( 0.1%, 99.0%): dropping after 12 ( 13) 10494 ( 0.1%, 99.1%): dropping after 11 ( 14) 7553 ( 0.1%, 99.2%): dropping after 14 ``` [^1]: i've incremented a counter in the place I now decrement the depth at and then printed it on drop r? `@compiler-errors`
2 parents caa8172 + 3465ce5 commit bd36e69
Copy full SHA for bd36e69

File tree

Expand file treeCollapse file tree

1 file changed

+53
-17
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+53
-17
lines changed

‎compiler/rustc_type_ir/src/fast_reject.rs

Copy file name to clipboardExpand all lines: compiler/rustc_type_ir/src/fast_reject.rs
+53-17Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -214,27 +214,47 @@ impl<I: Interner> DeepRejectCtxt<I, false, true> {
214214
impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_WITH_INFER: bool>
215215
DeepRejectCtxt<I, INSTANTIATE_LHS_WITH_INFER, INSTANTIATE_RHS_WITH_INFER>
216216
{
217+
// Quite arbitrary. Large enough to only affect a very tiny amount of impls/crates
218+
// and small enough to prevent hangs.
219+
const STARTING_DEPTH: usize = 8;
220+
217221
pub fn args_may_unify(
218222
self,
219223
obligation_args: I::GenericArgs,
220224
impl_args: I::GenericArgs,
221225
) -> bool {
226+
self.args_may_unify_inner(obligation_args, impl_args, Self::STARTING_DEPTH)
227+
}
228+
229+
pub fn types_may_unify(self, lhs: I::Ty, rhs: I::Ty) -> bool {
230+
self.types_may_unify_inner(lhs, rhs, Self::STARTING_DEPTH)
231+
}
232+
233+
fn args_may_unify_inner(
234+
self,
235+
obligation_args: I::GenericArgs,
236+
impl_args: I::GenericArgs,
237+
depth: usize,
238+
) -> bool {
239+
// No need to decrement the depth here as this function is only
240+
// recursively reachable via `types_may_unify_inner` which already
241+
// increments the depth for us.
222242
iter::zip(obligation_args.iter(), impl_args.iter()).all(|(obl, imp)| {
223243
match (obl.kind(), imp.kind()) {
224244
// We don't fast reject based on regions.
225245
(ty::GenericArgKind::Lifetime(_), ty::GenericArgKind::Lifetime(_)) => true,
226246
(ty::GenericArgKind::Type(obl), ty::GenericArgKind::Type(imp)) => {
227-
self.types_may_unify(obl, imp)
247+
self.types_may_unify_inner(obl, imp, depth)
228248
}
229249
(ty::GenericArgKind::Const(obl), ty::GenericArgKind::Const(imp)) => {
230-
self.consts_may_unify(obl, imp)
250+
self.consts_may_unify_inner(obl, imp)
231251
}
232252
_ => panic!("kind mismatch: {obl:?} {imp:?}"),
233253
}
234254
})
235255
}
236256

237-
pub fn types_may_unify(self, lhs: I::Ty, rhs: I::Ty) -> bool {
257+
fn types_may_unify_inner(self, lhs: I::Ty, rhs: I::Ty, depth: usize) -> bool {
238258
match rhs.kind() {
239259
// Start by checking whether the `rhs` type may unify with
240260
// pretty much everything. Just return `true` in that case.
@@ -273,18 +293,31 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
273293
| ty::Placeholder(_) => {}
274294
};
275295

296+
// The type system needs to support exponentially large types
297+
// as long as they are self-similar. While most other folders
298+
// use caching to handle them, this folder exists purely as a
299+
// perf optimization and is incredibly hot. In pretty much all
300+
// uses checking the cache is slower than simply recursing, so
301+
// we instead just add an arbitrary depth cutoff.
302+
//
303+
// We only decrement the depth here as the match on `rhs`
304+
// does not recurse.
305+
let Some(depth) = depth.checked_sub(1) else {
306+
return true;
307+
};
308+
276309
// For purely rigid types, use structural equivalence.
277310
match lhs.kind() {
278311
ty::Ref(_, lhs_ty, lhs_mutbl) => match rhs.kind() {
279312
ty::Ref(_, rhs_ty, rhs_mutbl) => {
280-
lhs_mutbl == rhs_mutbl && self.types_may_unify(lhs_ty, rhs_ty)
313+
lhs_mutbl == rhs_mutbl && self.types_may_unify_inner(lhs_ty, rhs_ty, depth)
281314
}
282315
_ => false,
283316
},
284317

285318
ty::Adt(lhs_def, lhs_args) => match rhs.kind() {
286319
ty::Adt(rhs_def, rhs_args) => {
287-
lhs_def == rhs_def && self.args_may_unify(lhs_args, rhs_args)
320+
lhs_def == rhs_def && self.args_may_unify_inner(lhs_args, rhs_args, depth)
288321
}
289322
_ => false,
290323
},
@@ -326,27 +359,28 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
326359
ty::Tuple(rhs) => {
327360
lhs.len() == rhs.len()
328361
&& iter::zip(lhs.iter(), rhs.iter())
329-
.all(|(lhs, rhs)| self.types_may_unify(lhs, rhs))
362+
.all(|(lhs, rhs)| self.types_may_unify_inner(lhs, rhs, depth))
330363
}
331364
_ => false,
332365
},
333366

334367
ty::Array(lhs_ty, lhs_len) => match rhs.kind() {
335368
ty::Array(rhs_ty, rhs_len) => {
336-
self.types_may_unify(lhs_ty, rhs_ty) && self.consts_may_unify(lhs_len, rhs_len)
369+
self.types_may_unify_inner(lhs_ty, rhs_ty, depth)
370+
&& self.consts_may_unify_inner(lhs_len, rhs_len)
337371
}
338372
_ => false,
339373
},
340374

341375
ty::RawPtr(lhs_ty, lhs_mutbl) => match rhs.kind() {
342376
ty::RawPtr(rhs_ty, rhs_mutbl) => {
343-
lhs_mutbl == rhs_mutbl && self.types_may_unify(lhs_ty, rhs_ty)
377+
lhs_mutbl == rhs_mutbl && self.types_may_unify_inner(lhs_ty, rhs_ty, depth)
344378
}
345379
_ => false,
346380
},
347381

348382
ty::Slice(lhs_ty) => {
349-
matches!(rhs.kind(), ty::Slice(rhs_ty) if self.types_may_unify(lhs_ty, rhs_ty))
383+
matches!(rhs.kind(), ty::Slice(rhs_ty) if self.types_may_unify_inner(lhs_ty, rhs_ty, depth))
350384
}
351385

352386
ty::Dynamic(lhs_preds, ..) => {
@@ -366,7 +400,7 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
366400
lhs_hdr == rhs_hdr
367401
&& lhs_sig_tys.len() == rhs_sig_tys.len()
368402
&& iter::zip(lhs_sig_tys.iter(), rhs_sig_tys.iter())
369-
.all(|(lhs, rhs)| self.types_may_unify(lhs, rhs))
403+
.all(|(lhs, rhs)| self.types_may_unify_inner(lhs, rhs, depth))
370404
}
371405
_ => false,
372406
},
@@ -375,49 +409,51 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
375409

376410
ty::FnDef(lhs_def_id, lhs_args) => match rhs.kind() {
377411
ty::FnDef(rhs_def_id, rhs_args) => {
378-
lhs_def_id == rhs_def_id && self.args_may_unify(lhs_args, rhs_args)
412+
lhs_def_id == rhs_def_id && self.args_may_unify_inner(lhs_args, rhs_args, depth)
379413
}
380414
_ => false,
381415
},
382416

383417
ty::Closure(lhs_def_id, lhs_args) => match rhs.kind() {
384418
ty::Closure(rhs_def_id, rhs_args) => {
385-
lhs_def_id == rhs_def_id && self.args_may_unify(lhs_args, rhs_args)
419+
lhs_def_id == rhs_def_id && self.args_may_unify_inner(lhs_args, rhs_args, depth)
386420
}
387421
_ => false,
388422
},
389423

390424
ty::CoroutineClosure(lhs_def_id, lhs_args) => match rhs.kind() {
391425
ty::CoroutineClosure(rhs_def_id, rhs_args) => {
392-
lhs_def_id == rhs_def_id && self.args_may_unify(lhs_args, rhs_args)
426+
lhs_def_id == rhs_def_id && self.args_may_unify_inner(lhs_args, rhs_args, depth)
393427
}
394428
_ => false,
395429
},
396430

397431
ty::Coroutine(lhs_def_id, lhs_args) => match rhs.kind() {
398432
ty::Coroutine(rhs_def_id, rhs_args) => {
399-
lhs_def_id == rhs_def_id && self.args_may_unify(lhs_args, rhs_args)
433+
lhs_def_id == rhs_def_id && self.args_may_unify_inner(lhs_args, rhs_args, depth)
400434
}
401435
_ => false,
402436
},
403437

404438
ty::CoroutineWitness(lhs_def_id, lhs_args) => match rhs.kind() {
405439
ty::CoroutineWitness(rhs_def_id, rhs_args) => {
406-
lhs_def_id == rhs_def_id && self.args_may_unify(lhs_args, rhs_args)
440+
lhs_def_id == rhs_def_id && self.args_may_unify_inner(lhs_args, rhs_args, depth)
407441
}
408442
_ => false,
409443
},
410444

411445
ty::Pat(lhs_ty, _) => {
412446
// FIXME(pattern_types): take pattern into account
413-
matches!(rhs.kind(), ty::Pat(rhs_ty, _) if self.types_may_unify(lhs_ty, rhs_ty))
447+
matches!(rhs.kind(), ty::Pat(rhs_ty, _) if self.types_may_unify_inner(lhs_ty, rhs_ty, depth))
414448
}
415449

416450
ty::Error(..) => true,
417451
}
418452
}
419453

420-
pub fn consts_may_unify(self, lhs: I::Const, rhs: I::Const) -> bool {
454+
// Unlike `types_may_unify_inner`, this does not take a depth as
455+
// we never recurse from this function.
456+
fn consts_may_unify_inner(self, lhs: I::Const, rhs: I::Const) -> bool {
421457
match rhs.kind() {
422458
ty::ConstKind::Param(_) => {
423459
if INSTANTIATE_RHS_WITH_INFER {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.