From 5cd9d929a9b7defd570711a29e70dca5072d2b37 Mon Sep 17 00:00:00 2001 From: Kevin Heavey Date: Tue, 21 Apr 2026 18:56:59 +0100 Subject: [PATCH] Avoid Vec allocation in TyCtxt::mk_place_elem `mk_place_elem` appends a single `PlaceElem` to an existing (interned) projection. The current implementation copies the projection into a fresh `Vec`, pushes the new element, and re-interns the slice, which allocates on the heap on every call. Feed the elements through `mk_place_elems_from_iter` so that `CollectAndApply`'s hand-unrolled stack fast path (up to 9 elements, in `rustc_type_ir::interner`) kicks in for the common case of short projections and the `Vec` allocation is skipped entirely. The behavior is identical for longer projections (the fast path falls back to a `Vec` internally). --- compiler/rustc_middle/src/ty/context.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 71b0077b62131..2f83378a2fe4f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2399,10 +2399,10 @@ impl<'tcx> TyCtxt<'tcx> { /// to build a full `Place` it's just a convenient way to grab a projection and modify it in /// flight. pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> { - let mut projection = place.projection.to_vec(); - projection.push(elem); - - Place { local: place.local, projection: self.mk_place_elems(&projection) } + Place { + local: place.local, + projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])), + } } pub fn mk_poly_existential_predicates(