Skip to content

refactor: Replace custom ThinVec with thin-vec crate #19440

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/hir-def/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ mbe.workspace = true
cfg.workspace = true
tt.workspace = true
span.workspace = true
thin-vec = "0.2.14"

[dev-dependencies]
expect-test.workspace = true
Expand Down
31 changes: 19 additions & 12 deletions crates/hir-def/src/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ use hir_expand::{
};
use intern::sym;
use la_arena::{Arena, RawIdx};
use stdx::{
impl_from,
thin_vec::{EmptyOptimizedThinVec, ThinVec},
};
use stdx::impl_from;
use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds};
use thin_vec::ThinVec;
use triomphe::Arc;

use crate::{
Expand Down Expand Up @@ -753,12 +751,17 @@ fn copy_type_ref(
) -> TypeRefId {
let result = match &from[type_ref] {
TypeRef::Fn(fn_) => {
let params = fn_.params().iter().map(|(name, param_type)| {
let params = fn_.params.iter().map(|(name, param_type)| {
(name.clone(), copy_type_ref(*param_type, from, from_source_map, to, to_source_map))
});
TypeRef::Fn(FnType::new(fn_.is_varargs(), fn_.is_unsafe(), fn_.abi().clone(), params))
TypeRef::Fn(Box::new(FnType {
params: params.collect(),
is_varargs: fn_.is_varargs,
is_unsafe: fn_.is_unsafe,
abi: fn_.abi.clone(),
}))
}
TypeRef::Tuple(types) => TypeRef::Tuple(EmptyOptimizedThinVec::from_iter(
TypeRef::Tuple(types) => TypeRef::Tuple(ThinVec::from_iter(
types.iter().map(|&t| copy_type_ref(t, from, from_source_map, to, to_source_map)),
)),
&TypeRef::RawPtr(type_ref, mutbl) => TypeRef::RawPtr(
Expand Down Expand Up @@ -817,13 +820,17 @@ fn copy_path(
Path::BarePath(mod_path) => Path::BarePath(mod_path.clone()),
Path::Normal(path) => {
let type_anchor = path
.type_anchor()
.type_anchor
.map(|type_ref| copy_type_ref(type_ref, from, from_source_map, to, to_source_map));
let mod_path = path.mod_path().clone();
let generic_args = path.generic_args().iter().map(|generic_args| {
let mod_path = path.mod_path.clone();
let generic_args = path.generic_args.iter().map(|generic_args| {
copy_generic_args(generic_args, from, from_source_map, to, to_source_map)
});
Path::Normal(NormalPath::new(type_anchor, mod_path, generic_args))
Path::Normal(Box::new(NormalPath {
generic_args: generic_args.collect(),
type_anchor,
mod_path,
}))
}
Path::LangItem(lang_item, name) => Path::LangItem(*lang_item, name.clone()),
}
Expand Down Expand Up @@ -879,7 +886,7 @@ fn copy_type_bounds<'a>(
from_source_map: &'a TypesSourceMap,
to: &'a mut TypesMap,
to_source_map: &'a mut TypesSourceMap,
) -> impl stdx::thin_vec::TrustedLen<Item = TypeBound> + 'a {
) -> impl Iterator<Item = TypeBound> + 'a {
bounds.iter().map(|bound| copy_type_bound(bound, from, from_source_map, to, to_source_map))
}

Expand Down
36 changes: 20 additions & 16 deletions crates/hir-def/src/hir/type_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ use hir_expand::{
use intern::{Symbol, sym};
use la_arena::{Arena, ArenaMap, Idx};
use span::Edition;
use stdx::thin_vec::{EmptyOptimizedThinVec, ThinVec, thin_vec_with_header_struct};
use syntax::{
AstPtr,
ast::{self, HasGenericArgs, HasName, IsString},
};
use thin_vec::ThinVec;

use crate::{
SyntheticSyntax,
Expand Down Expand Up @@ -120,13 +120,12 @@ impl TraitRef {
}
}

thin_vec_with_header_struct! {
pub new(pub(crate)) struct FnType, FnTypeHeader {
pub params: [(Option<Name>, TypeRefId)],
pub is_varargs: bool,
pub is_unsafe: bool,
pub abi: Option<Symbol>; ref,
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct FnType {
pub params: Box<[(Option<Name>, TypeRefId)]>,
pub is_varargs: bool,
pub is_unsafe: bool,
pub abi: Option<Symbol>,
}

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
Expand All @@ -148,14 +147,14 @@ pub struct RefType {
pub enum TypeRef {
Never,
Placeholder,
Tuple(EmptyOptimizedThinVec<TypeRefId>),
Tuple(ThinVec<TypeRefId>),
Path(Path),
RawPtr(TypeRefId, Mutability),
Reference(Box<RefType>),
Array(Box<ArrayType>),
Slice(TypeRefId),
/// A fn pointer. Last element of the vector is the return type.
Fn(FnType),
Fn(Box<FnType>),
ImplTrait(ThinVec<TypeBound>),
DynTrait(ThinVec<TypeBound>),
Macro(AstId<ast::MacroCall>),
Expand Down Expand Up @@ -273,9 +272,9 @@ impl TypeRef {
pub fn from_ast(ctx: &mut LowerCtx<'_>, node: ast::Type) -> TypeRefId {
let ty = match &node {
ast::Type::ParenType(inner) => return TypeRef::from_ast_opt(ctx, inner.ty()),
ast::Type::TupleType(inner) => TypeRef::Tuple(EmptyOptimizedThinVec::from_iter(
Vec::from_iter(inner.fields().map(|it| TypeRef::from_ast(ctx, it))),
)),
ast::Type::TupleType(inner) => TypeRef::Tuple(ThinVec::from_iter(Vec::from_iter(
inner.fields().map(|it| TypeRef::from_ast(ctx, it)),
))),
ast::Type::NeverType(..) => TypeRef::Never,
ast::Type::PathType(inner) => {
// FIXME: Use `Path::from_src`
Expand Down Expand Up @@ -342,7 +341,12 @@ impl TypeRef {

let abi = inner.abi().map(lower_abi);
params.push((None, ret_ty));
TypeRef::Fn(FnType::new(is_varargs, inner.unsafe_token().is_some(), abi, params))
TypeRef::Fn(Box::new(FnType {
params: params.into(),
is_varargs,
is_unsafe: inner.unsafe_token().is_some(),
abi,
}))
}
// for types are close enough for our purposes to the inner type for now...
ast::Type::ForType(inner) => return TypeRef::from_ast_opt(ctx, inner.ty()),
Expand Down Expand Up @@ -375,7 +379,7 @@ impl TypeRef {
}

pub(crate) fn unit() -> TypeRef {
TypeRef::Tuple(EmptyOptimizedThinVec::empty())
TypeRef::Tuple(ThinVec::new())
}

pub fn walk(this: TypeRefId, map: &TypesMap, f: &mut impl FnMut(&TypeRef)) {
Expand All @@ -386,7 +390,7 @@ impl TypeRef {
f(type_ref);
match type_ref {
TypeRef::Fn(fn_) => {
fn_.params().iter().for_each(|&(_, param_type)| go(param_type, f, map))
fn_.params.iter().for_each(|&(_, param_type)| go(param_type, f, map))
}
TypeRef::Tuple(types) => types.iter().for_each(|&t| go(t, f, map)),
TypeRef::RawPtr(type_ref, _) | TypeRef::Slice(type_ref) => go(*type_ref, f, map),
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-def/src/item_tree/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ use intern::{Symbol, sym};
use la_arena::Arena;
use rustc_hash::FxHashMap;
use span::{AstIdMap, SyntaxContext};
use stdx::thin_vec::ThinVec;
use syntax::{
AstNode,
ast::{self, HasModuleItem, HasName, HasTypeBounds, IsString},
};
use thin_vec::ThinVec;
use triomphe::Arc;

use crate::{
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-def/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::{cell::OnceCell, mem};

use hir_expand::{AstId, HirFileId, InFile, span_map::SpanMap};
use span::{AstIdMap, AstIdNode, Edition, EditionedFileId, FileId, RealSpanMap};
use stdx::thin_vec::ThinVec;
use syntax::ast;
use thin_vec::ThinVec;
use triomphe::Arc;

use crate::{
Expand Down
52 changes: 27 additions & 25 deletions crates/hir-def/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use crate::{
use hir_expand::name::Name;
use intern::Interned;
use span::Edition;
use stdx::thin_vec::thin_vec_with_header_struct;
use syntax::ast;

pub use hir_expand::mod_path::{ModPath, PathKind, path};
Expand Down Expand Up @@ -58,7 +57,7 @@ pub enum Path {
/// this is not a problem since many more paths have generics than a type anchor).
BarePath(Interned<ModPath>),
/// `Path::Normal` will always have either generics or type anchor.
Normal(NormalPath),
Normal(Box<NormalPath>),
/// A link to a lang item. It is used in desugaring of things like `it?`. We can show these
/// links via a normal path since they might be private and not accessible in the usage place.
LangItem(LangItemTarget, Option<Name>),
Expand All @@ -71,12 +70,11 @@ const _: () = {
assert!(size_of::<Option<Path>>() == 16);
};

thin_vec_with_header_struct! {
pub new(pub(crate)) struct NormalPath, NormalPathHeader {
pub generic_args: [Option<GenericArgs>],
pub type_anchor: Option<TypeRefId>,
pub mod_path: Interned<ModPath>; ref,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct NormalPath {
pub generic_args: Box<[Option<GenericArgs>]>,
pub type_anchor: Option<TypeRefId>,
pub mod_path: Interned<ModPath>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -143,7 +141,11 @@ impl Path {

/// Converts a known mod path to `Path`.
pub fn from_known_path(path: ModPath, generic_args: Vec<Option<GenericArgs>>) -> Path {
Path::Normal(NormalPath::new(None, Interned::new(path), generic_args))
Path::Normal(Box::new(NormalPath {
generic_args: generic_args.into_boxed_slice(),
type_anchor: None,
mod_path: Interned::new(path),
}))
}

/// Converts a known mod path to `Path`.
Expand All @@ -155,23 +157,23 @@ impl Path {
pub fn kind(&self) -> &PathKind {
match self {
Path::BarePath(mod_path) => &mod_path.kind,
Path::Normal(path) => &path.mod_path().kind,
Path::Normal(path) => &path.mod_path.kind,
Path::LangItem(..) => &PathKind::Abs,
}
}

#[inline]
pub fn type_anchor(&self) -> Option<TypeRefId> {
match self {
Path::Normal(path) => path.type_anchor(),
Path::Normal(path) => path.type_anchor,
Path::LangItem(..) | Path::BarePath(_) => None,
}
}

#[inline]
pub fn generic_args(&self) -> Option<&[Option<GenericArgs>]> {
match self {
Path::Normal(path) => Some(path.generic_args()),
Path::Normal(path) => Some(&path.generic_args),
Path::LangItem(..) | Path::BarePath(_) => None,
}
}
Expand All @@ -182,8 +184,8 @@ impl Path {
PathSegments { segments: mod_path.segments(), generic_args: None }
}
Path::Normal(path) => PathSegments {
segments: path.mod_path().segments(),
generic_args: Some(path.generic_args()),
segments: path.mod_path.segments(),
generic_args: Some(&path.generic_args),
},
Path::LangItem(_, seg) => PathSegments { segments: seg.as_slice(), generic_args: None },
}
Expand All @@ -192,7 +194,7 @@ impl Path {
pub fn mod_path(&self) -> Option<&ModPath> {
match self {
Path::BarePath(mod_path) => Some(mod_path),
Path::Normal(path) => Some(path.mod_path()),
Path::Normal(path) => Some(&path.mod_path),
Path::LangItem(..) => None,
}
}
Expand All @@ -209,12 +211,12 @@ impl Path {
))))
}
Path::Normal(path) => {
let mod_path = path.mod_path();
let mod_path = &path.mod_path;
if mod_path.is_ident() {
return None;
}
let type_anchor = path.type_anchor();
let generic_args = path.generic_args();
let type_anchor = path.type_anchor;
let generic_args = &path.generic_args;
let qualifier_mod_path = Interned::new(ModPath::from_segments(
mod_path.kind,
mod_path.segments()[..mod_path.segments().len() - 1].iter().cloned(),
Expand All @@ -223,11 +225,11 @@ impl Path {
if type_anchor.is_none() && qualifier_generic_args.iter().all(|it| it.is_none()) {
Some(Path::BarePath(qualifier_mod_path))
} else {
Some(Path::Normal(NormalPath::new(
Some(Path::Normal(Box::new(NormalPath {
type_anchor,
qualifier_mod_path,
qualifier_generic_args.iter().cloned(),
)))
mod_path: qualifier_mod_path,
generic_args: qualifier_generic_args.iter().cloned().collect(),
})))
}
}
Path::LangItem(..) => None,
Expand All @@ -238,9 +240,9 @@ impl Path {
match self {
Path::BarePath(mod_path) => mod_path.is_Self(),
Path::Normal(path) => {
path.type_anchor().is_none()
&& path.mod_path().is_Self()
&& path.generic_args().iter().all(|args| args.is_none())
path.type_anchor.is_none()
&& path.mod_path.is_Self()
&& path.generic_args.iter().all(|args| args.is_none())
}
Path::LangItem(..) => false,
}
Expand Down
10 changes: 7 additions & 3 deletions crates/hir-def/src/path/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use hir_expand::{
name::{AsName, Name},
};
use intern::{Interned, sym};
use stdx::thin_vec::EmptyOptimizedThinVec;
use syntax::ast::{self, AstNode, HasGenericArgs, HasTypeBounds};
use thin_vec::ThinVec;

use crate::{
path::{
Expand Down Expand Up @@ -213,7 +213,11 @@ pub(super) fn lower_path(ctx: &mut LowerCtx<'_>, mut path: ast::Path) -> Option<
if type_anchor.is_none() && generic_args.is_empty() {
return Some(Path::BarePath(mod_path));
} else {
return Some(Path::Normal(NormalPath::new(type_anchor, mod_path, generic_args)));
return Some(Path::Normal(Box::new(NormalPath {
generic_args: generic_args.into_boxed_slice(),
type_anchor,
mod_path,
})));
}

fn qualifier(path: &ast::Path) -> Option<ast::Path> {
Expand Down Expand Up @@ -344,7 +348,7 @@ fn lower_generic_args_from_fn_path(
param_types.push(type_ref);
}
let args = Box::new([GenericArg::Type(
ctx.alloc_type_ref_desugared(TypeRef::Tuple(EmptyOptimizedThinVec::from_iter(param_types))),
ctx.alloc_type_ref_desugared(TypeRef::Tuple(ThinVec::from_iter(param_types))),
)]);
let bindings = if let Some(ret_type) = ret_type {
let type_ref = TypeRef::from_ast_opt(ctx, ret_type.ty());
Expand Down
Loading
Loading