Skip to content

Commit 8dad289

Browse files
authored
[ty] Add Salsa caching to ClassLiteral::fields (#21512)
1 parent f67236b commit 8dad289

File tree

9 files changed

+93
-93
lines changed

9 files changed

+93
-93
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ty/docs/rules.md

Lines changed: 68 additions & 68 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ty_python_semantic/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ camino = { workspace = true }
3232
colored = { workspace = true }
3333
compact_str = { workspace = true }
3434
drop_bomb = { workspace = true }
35-
get-size2 = { workspace = true }
35+
get-size2 = { workspace = true, features = ["indexmap"]}
3636
indexmap = { workspace = true }
3737
itertools = { workspace = true }
3838
ordermap = { workspace = true }

crates/ty_python_semantic/src/types/bound_super.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ impl<'db> BoundSuperType<'db> {
396396
let mut key_builder = UnionBuilder::new(db);
397397
let mut value_builder = UnionBuilder::new(db);
398398
for (name, field) in td.items(db) {
399-
key_builder = key_builder.add(Type::string_literal(db, &name));
399+
key_builder = key_builder.add(Type::string_literal(db, name));
400400
value_builder = value_builder.add(field.declared_ty);
401401
}
402402
return delegate_to(

crates/ty_python_semantic/src/types/call/bind.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3036,8 +3036,8 @@ impl<'a, 'db> ArgumentTypeChecker<'a, 'db> {
30363036
if let Type::TypedDict(typed_dict) = argument_type {
30373037
for (argument_type, parameter_index) in typed_dict
30383038
.items(self.db)
3039-
.iter()
3040-
.map(|(_, field)| field.declared_ty)
3039+
.values()
3040+
.map(|field| field.declared_ty)
30413041
.zip(&self.argument_matches[argument_index].parameters)
30423042
{
30433043
self.check_argument_type(

crates/ty_python_semantic/src/types/class.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use super::{
77
SpecialFormType, SubclassOfType, Truthiness, Type, TypeQualifiers, class_base::ClassBase,
88
function::FunctionType, infer_expression_type, infer_unpack_types,
99
};
10-
use crate::FxOrderMap;
1110
use crate::module_resolver::KnownModule;
1211
use crate::place::TypeOrigin;
1312
use crate::semantic_index::definition::{Definition, DefinitionState};
@@ -128,7 +127,7 @@ fn try_metaclass_cycle_initial<'db>(
128127
}
129128

130129
/// A category of classes with code generation capabilities (with synthesized methods).
131-
#[derive(Clone, Copy, Debug, PartialEq, salsa::Update, get_size2::GetSize)]
130+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, salsa::Update, get_size2::GetSize)]
132131
pub(crate) enum CodeGeneratorKind<'db> {
133132
/// Classes decorated with `@dataclass` or similar dataclass-like decorators
134133
DataclassLike(Option<DataclassTransformerParams<'db>>),
@@ -1253,7 +1252,7 @@ impl MethodDecorator {
12531252
}
12541253

12551254
/// Kind-specific metadata for different types of fields
1256-
#[derive(Debug, Clone, PartialEq, Eq)]
1255+
#[derive(Debug, Clone, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
12571256
pub(crate) enum FieldKind<'db> {
12581257
/// `NamedTuple` field metadata
12591258
NamedTuple { default_ty: Option<Type<'db>> },
@@ -1281,7 +1280,7 @@ pub(crate) enum FieldKind<'db> {
12811280
}
12821281

12831282
/// Metadata regarding a dataclass field/attribute or a `TypedDict` "item" / key-value pair.
1284-
#[derive(Debug, Clone, PartialEq, Eq)]
1283+
#[derive(Debug, Clone, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
12851284
pub(crate) struct Field<'db> {
12861285
/// The declared type of the field
12871286
pub(crate) declared_ty: Type<'db>,
@@ -2329,7 +2328,8 @@ impl<'db> ClassLiteral<'db> {
23292328
|| kw_only.unwrap_or(has_dataclass_param(DataclassFlags::KW_ONLY));
23302329

23312330
// Use the alias name if provided, otherwise use the field name
2332-
let parameter_name = alias.map(Name::new).unwrap_or(field_name);
2331+
let parameter_name =
2332+
Name::new(alias.map(|alias| &**alias).unwrap_or(&**field_name));
23332333

23342334
let mut parameter = if is_kw_only {
23352335
Parameter::keyword_only(parameter_name)
@@ -2595,7 +2595,7 @@ impl<'db> ClassLiteral<'db> {
25952595
(CodeGeneratorKind::TypedDict, "get") => {
25962596
let overloads = self
25972597
.fields(db, specialization, field_policy)
2598-
.into_iter()
2598+
.iter()
25992599
.flat_map(|(name, field)| {
26002600
let key_type =
26012601
Type::StringLiteral(StringLiteralType::new(db, name.as_str()));
@@ -2824,12 +2824,13 @@ impl<'db> ClassLiteral<'db> {
28242824
/// Returns a list of all annotated attributes defined in this class, or any of its superclasses.
28252825
///
28262826
/// See [`ClassLiteral::own_fields`] for more details.
2827+
#[salsa::tracked(returns(ref), heap_size=get_size2::GetSize::get_heap_size)]
28272828
pub(crate) fn fields(
28282829
self,
28292830
db: &'db dyn Db,
28302831
specialization: Option<Specialization<'db>>,
2831-
field_policy: CodeGeneratorKind,
2832-
) -> FxOrderMap<Name, Field<'db>> {
2832+
field_policy: CodeGeneratorKind<'db>,
2833+
) -> FxIndexMap<Name, Field<'db>> {
28332834
if field_policy == CodeGeneratorKind::NamedTuple {
28342835
// NamedTuples do not allow multiple inheritance, so it is sufficient to enumerate the
28352836
// fields of this class only.
@@ -2877,8 +2878,8 @@ impl<'db> ClassLiteral<'db> {
28772878
db: &'db dyn Db,
28782879
specialization: Option<Specialization<'db>>,
28792880
field_policy: CodeGeneratorKind,
2880-
) -> FxOrderMap<Name, Field<'db>> {
2881-
let mut attributes = FxOrderMap::default();
2881+
) -> FxIndexMap<Name, Field<'db>> {
2882+
let mut attributes = FxIndexMap::default();
28822883

28832884
let class_body_scope = self.body_scope(db);
28842885
let table = place_table(db, class_body_scope);

crates/ty_python_semantic/src/types/diagnostic.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ use crate::types::{
2626
ProtocolInstanceType, SpecialFormType, SubclassOfInner, Type, TypeContext, binding_type,
2727
infer_isolated_expression, protocol_class::ProtocolClass,
2828
};
29-
use crate::{
30-
Db, DisplaySettings, FxIndexMap, FxOrderMap, Module, ModuleName, Program, declare_lint,
31-
};
29+
use crate::{Db, DisplaySettings, FxIndexMap, Module, ModuleName, Program, declare_lint};
3230
use itertools::Itertools;
3331
use ruff_db::diagnostic::{Annotation, Diagnostic, Span, SubDiagnostic, SubDiagnosticSeverity};
3432
use ruff_db::source::source_text;
@@ -3192,7 +3190,7 @@ pub(crate) fn report_invalid_key_on_typed_dict<'db>(
31923190
typed_dict_ty: Type<'db>,
31933191
full_object_ty: Option<Type<'db>>,
31943192
key_ty: Type<'db>,
3195-
items: &FxOrderMap<Name, Field<'db>>,
3193+
items: &FxIndexMap<Name, Field<'db>>,
31963194
) {
31973195
let db = context.db();
31983196
if let Some(builder) = context.report_lint(&INVALID_KEY, key_node) {
@@ -3221,7 +3219,7 @@ pub(crate) fn report_invalid_key_on_typed_dict<'db>(
32213219
.message(format_args!("TypedDict `{typed_dict_name}`"))
32223220
});
32233221

3224-
let existing_keys = items.iter().map(|(name, _)| name.as_str());
3222+
let existing_keys = items.keys();
32253223
if let Some(suggestion) = did_you_mean(existing_keys, key) {
32263224
if key_node.is_expr_string_literal() {
32273225
diagnostic

crates/ty_python_semantic/src/types/infer/builder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
922922

923923
let kw_only_sentinel_fields: Vec<_> = class
924924
.fields(self.db(), specialization, field_policy)
925-
.into_iter()
925+
.iter()
926926
.filter_map(|(name, field)| {
927927
field.is_kw_only_sentinel(self.db()).then_some(name)
928928
})
@@ -7954,7 +7954,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
79547954
Type::TypedDict(typed_dict_ty),
79557955
None,
79567956
key_ty,
7957-
&items,
7957+
items,
79587958
);
79597959
// Return `Unknown` to prevent the overload system from generating its own error
79607960
return Type::unknown();
@@ -11295,7 +11295,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
1129511295
value_ty,
1129611296
None,
1129711297
slice_ty,
11298-
&typed_dict.items(db),
11298+
typed_dict.items(db),
1129911299
);
1130011300
} else {
1130111301
if let Some(builder) =

crates/ty_python_semantic/src/types/typed_dict.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use super::diagnostic::{
1313
};
1414
use super::{ApplyTypeMappingVisitor, Type, TypeMapping, visitor};
1515
use crate::types::TypeContext;
16-
use crate::{Db, FxOrderMap};
16+
use crate::{Db, FxIndexMap};
1717

1818
use ordermap::OrderSet;
1919

@@ -54,7 +54,7 @@ impl<'db> TypedDictType<'db> {
5454
self.defining_class
5555
}
5656

57-
pub(crate) fn items(self, db: &'db dyn Db) -> FxOrderMap<Name, Field<'db>> {
57+
pub(crate) fn items(self, db: &'db dyn Db) -> &'db FxIndexMap<Name, Field<'db>> {
5858
let (class_literal, specialization) = self.defining_class.class_literal(db);
5959
class_literal.fields(db, specialization, CodeGeneratorKind::TypedDict)
6060
}
@@ -165,7 +165,7 @@ pub(super) fn validate_typed_dict_key_assignment<'db, 'ast>(
165165
Type::TypedDict(typed_dict),
166166
full_object_ty,
167167
Type::string_literal(db, key),
168-
&items,
168+
items,
169169
);
170170
}
171171

0 commit comments

Comments
 (0)