Skip to content

Commit ef7aa51

Browse files
committed
Auto merge of #136593 - lukas-code:ty-value-perf, r=oli-obk
valtree performance tuning Summary: This PR makes type checking of code with many type-level constants faster. After rust-lang/rust#136180 was merged, we observed a small perf regression (rust-lang/rust#136318 (comment)). This happened because that PR introduced additional copies in the fast reject code path for consts, which is very hot for certain crates: https://github.com/rust-lang/rust/blob/6c1d960d88dd3755548b3818630acb63fa98187e/compiler/rustc_type_ir/src/fast_reject.rs#L486-L487 This PR improves the performance again by properly interning the valtrees so that copying and comparing them becomes faster. This will become especially useful with `feature(adt_const_params)`, so the fast reject code doesn't have to do a deep compare of the valtrees. Note that we can't just compare the interned consts themselves in the fast reject, because sometimes `'static` lifetimes in the type are be replaced with inference variables (due to canonicalization) on one side but not the other. A less invasive alternative that I considered is simply avoiding copies introduced by rust-lang/rust#136180 and comparing the valtrees it in-place (see commit: rust-lang/rust@9e91e50 / perf results: rust-lang/rust#136593 (comment)), however that was still measurably slower than interning. There are some minor regressions in secondary benchmarks: These happen due to changes in memory allocations and seem acceptable to me. The crates that make heavy use of valtrees show no significant changes in memory usage.
2 parents 7cd3b8c + a75cc61 commit ef7aa51

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

clippy_lints/src/non_copy_const.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@ impl<'tcx> NonCopyConst<'tcx> {
179179
}
180180

181181
fn is_value_unfrozen_raw_inner(cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> bool {
182-
// No branch that we check (yet) should continue if val isn't a ValTree::Branch
183-
let ty::ValTree::Branch(val) = val else { return false };
182+
// No branch that we check (yet) should continue if val isn't a branch
183+
let Some(val) = val.try_to_branch() else { return false };
184184
match *ty.kind() {
185185
// the fact that we have to dig into every structs to search enums
186186
// leads us to the point checking `UnsafeCell` directly is the only option.
@@ -192,9 +192,10 @@ impl<'tcx> NonCopyConst<'tcx> {
192192
.iter()
193193
.any(|field| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),
194194
ty::Adt(def, args) if def.is_enum() => {
195-
let Some((&ty::ValTree::Leaf(variant_index), fields)) = val.split_first() else {
195+
let Some((&variant_valtree, fields)) = val.split_first() else {
196196
return false;
197197
};
198+
let variant_index = variant_valtree.unwrap_leaf();
198199
let variant_index = VariantIdx::from_u32(variant_index.to_u32());
199200
fields
200201
.iter()

0 commit comments

Comments
 (0)