[ty] Use `ThinVec` in various places

This commit is contained in:
Micha Reiser 2025-07-18 09:19:48 +02:00
parent b8d2037373
commit 3e7cfca47c
No known key found for this signature in database
9 changed files with 122 additions and 12 deletions

1
Cargo.lock generated
View File

@ -4287,6 +4287,7 @@ dependencies = [
"strum_macros",
"tempfile",
"test-case",
"thin-vec",
"thiserror 2.0.12",
"tracing",
"ty_python_semantic",

View File

@ -163,6 +163,7 @@ strum_macros = { version = "0.27.0" }
syn = { version = "2.0.55" }
tempfile = { version = "3.9.0" }
test-case = { version = "3.3.1" }
thin-vec = { version = "0.2.14" }
thiserror = { version = "2.0.0" }
tikv-jemallocator = { version = "0.6.0" }
toml = { version = "0.9.0" }

View File

@ -35,6 +35,7 @@ indexmap = { workspace = true }
itertools = { workspace = true }
ordermap = { workspace = true }
salsa = { workspace = true, features = ["compact_str"] }
thin-vec = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
rustc-hash = { workspace = true }

View File

@ -26,6 +26,7 @@ use crate::semantic_index::place::{
};
use crate::semantic_index::use_def::{EagerSnapshotKey, ScopedEagerSnapshotId, UseDefMap};
use crate::semantic_model::HasTrackedScope;
use crate::util::get_size::ThinVecSized;
use crate::util::get_size::untracked_arc_size;
pub mod ast_ids;
@ -238,7 +239,7 @@ pub(crate) struct SemanticIndex<'db> {
eager_snapshots: FxHashMap<EagerSnapshotKey, ScopedEagerSnapshotId>,
/// List of all semantic syntax errors in this file.
semantic_syntax_errors: Vec<SemanticSyntaxError>,
semantic_syntax_errors: ThinVecSized<SemanticSyntaxError>,
/// Set of all generator functions in this file.
generator_functions: FxHashSet<FileScopeId>,

View File

@ -115,7 +115,7 @@ pub(super) struct SemanticIndexBuilder<'db, 'ast> {
generator_functions: FxHashSet<FileScopeId>,
eager_snapshots: FxHashMap<EagerSnapshotKey, ScopedEagerSnapshotId>,
/// Errors collected by the `semantic_checker`.
semantic_syntax_errors: RefCell<Vec<SemanticSyntaxError>>,
semantic_syntax_errors: RefCell<thin_vec::ThinVec<SemanticSyntaxError>>,
}
impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
@ -1063,7 +1063,7 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
imported_modules: Arc::new(self.imported_modules),
has_future_annotations: self.has_future_annotations,
eager_snapshots: self.eager_snapshots,
semantic_syntax_errors: self.semantic_syntax_errors.into_inner(),
semantic_syntax_errors: self.semantic_syntax_errors.into_inner().into(),
generator_functions: self.generator_functions,
}
}

View File

@ -10,13 +10,13 @@ use ruff_index::{IndexVec, newtype_index};
use ruff_python_ast as ast;
use ruff_python_ast::name::Name;
use rustc_hash::FxHasher;
use smallvec::{SmallVec, smallvec};
use crate::Db;
use crate::ast_node_ref::AstNodeRef;
use crate::node_key::NodeKey;
use crate::semantic_index::reachability_constraints::ScopedReachabilityConstraintId;
use crate::semantic_index::{PlaceSet, SemanticIndex, semantic_index};
use crate::util::get_size::ThinVecSized;
#[derive(Debug, Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
pub(crate) enum PlaceExprSubSegment {
@ -41,7 +41,7 @@ impl PlaceExprSubSegment {
#[derive(Eq, PartialEq, Debug, get_size2::GetSize)]
pub struct PlaceExpr {
root_name: Name,
sub_segments: SmallVec<[PlaceExprSubSegment; 1]>,
sub_segments: ThinVecSized<PlaceExprSubSegment>,
}
impl std::fmt::Display for PlaceExpr {
@ -165,7 +165,7 @@ impl PlaceExpr {
pub(crate) fn name(name: Name) -> Self {
Self {
root_name: name,
sub_segments: smallvec![],
sub_segments: ThinVecSized::new(),
}
}
@ -230,7 +230,9 @@ impl std::fmt::Display for PlaceExprWithFlags {
}
impl PlaceExprWithFlags {
pub(crate) fn new(expr: PlaceExpr) -> Self {
pub(crate) fn new(mut expr: PlaceExpr) -> Self {
expr.sub_segments.shrink_to_fit();
PlaceExprWithFlags {
expr,
flags: PlaceFlags::empty(),

View File

@ -93,7 +93,7 @@ mod definition;
#[cfg(test)]
mod property_tests;
pub fn check_types(db: &dyn Db, file: File) -> Vec<Diagnostic> {
pub fn check_types(db: &dyn Db, file: File) -> thin_vec::ThinVec<Diagnostic> {
let _span = tracing::trace_span!("check_types", ?file).entered();
tracing::debug!("Checking file '{path}'", path = file.path(db));

View File

@ -18,6 +18,7 @@ use crate::types::string_annotation::{
use crate::types::tuple::TupleType;
use crate::types::{SpecialFormType, Type, protocol_class::ProtocolClassLiteral};
use crate::util::diagnostics::format_enumeration;
use crate::util::get_size::ThinVecSized;
use crate::{Db, FxIndexMap, Module, ModuleName, Program, declare_lint};
use itertools::Itertools;
use ruff_db::diagnostic::{Annotation, Diagnostic, Severity, SubDiagnostic};
@ -1614,7 +1615,7 @@ declare_lint! {
/// A collection of type check diagnostics.
#[derive(Default, Eq, PartialEq, get_size2::GetSize)]
pub struct TypeCheckDiagnostics {
diagnostics: Vec<Diagnostic>,
diagnostics: ThinVecSized<Diagnostic>,
used_suppressions: FxHashSet<FileSuppressionId>,
}
@ -1649,8 +1650,8 @@ impl TypeCheckDiagnostics {
self.diagnostics.shrink_to_fit();
}
pub(crate) fn into_vec(self) -> Vec<Diagnostic> {
self.diagnostics
pub(crate) fn into_vec(self) -> thin_vec::ThinVec<Diagnostic> {
self.diagnostics.into_inner()
}
pub fn iter(&self) -> std::slice::Iter<'_, Diagnostic> {
@ -1666,7 +1667,7 @@ impl std::fmt::Debug for TypeCheckDiagnostics {
impl IntoIterator for TypeCheckDiagnostics {
type Item = Diagnostic;
type IntoIter = std::vec::IntoIter<Diagnostic>;
type IntoIter = thin_vec::IntoIter<Diagnostic>;
fn into_iter(self) -> Self::IntoIter {
self.diagnostics.into_iter()

View File

@ -1,3 +1,4 @@
use std::ops::{Deref, DerefMut};
use std::sync::Arc;
use get_size2::GetSize;
@ -13,3 +14,105 @@ where
{
T::get_heap_size(&**arc)
}
#[derive(Clone, Hash, PartialEq, Eq)]
pub(crate) struct ThinVecSized<T>(thin_vec::ThinVec<T>);
impl<T> ThinVecSized<T> {
pub(crate) fn into_inner(self) -> thin_vec::ThinVec<T> {
self.0
}
pub(crate) fn new() -> Self {
Self(thin_vec::ThinVec::new())
}
}
impl<T> Default for ThinVecSized<T> {
fn default() -> Self {
Self::new()
}
}
#[allow(unsafe_code)]
unsafe impl<T> salsa::Update for ThinVecSized<T>
where
T: salsa::Update,
{
unsafe fn maybe_update(old_pointer: *mut Self, new_value: Self) -> bool {
let old: &mut Self = unsafe { &mut *old_pointer };
unsafe { salsa::Update::maybe_update(&raw mut old.0, new_value.0) }
}
}
impl<T> std::fmt::Debug for ThinVecSized<T>
where
T: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl<T> From<thin_vec::ThinVec<T>> for ThinVecSized<T> {
fn from(vec: thin_vec::ThinVec<T>) -> Self {
Self(vec)
}
}
impl<T> Deref for ThinVecSized<T> {
type Target = thin_vec::ThinVec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for ThinVecSized<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> GetSize for ThinVecSized<T>
where
T: GetSize,
{
fn get_heap_size(&self) -> usize {
let mut total = 0;
for v in self {
total += GetSize::get_size(v);
}
let additional: usize = self.capacity() - self.len();
total += additional * T::get_stack_size();
total
}
}
impl<'a, T> IntoIterator for &'a ThinVecSized<T> {
type Item = &'a T;
type IntoIter = std::slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl<'a, T> IntoIterator for &'a mut ThinVecSized<T> {
type Item = &'a mut T;
type IntoIter = std::slice::IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter_mut()
}
}
impl<T> IntoIterator for ThinVecSized<T> {
type Item = T;
type IntoIter = thin_vec::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}