Skip to content

Commit 2f03837

Browse files
committed
speedup DateType benchmark
1 parent c1ef999 commit 2f03837

File tree

2 files changed

+89
-59
lines changed

2 files changed

+89
-59
lines changed

crates/ty_python_semantic/resources/mdtest/protocols.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,6 @@ reveal_protocol_interface(SupportsIndex)
418418
# error: [revealed-type] "Revealed protocol interface: `{"__abs__": MethodMember(`(self) -> Unknown`)}`"
419419
reveal_protocol_interface(SupportsAbs)
420420

421-
422421
# error: [invalid-argument-type] "Invalid argument to `reveal_protocol_interface`: Only protocol classes can be passed to `reveal_protocol_interface`"
423422
reveal_protocol_interface(int)
424423
# error: [invalid-argument-type] "Argument to function `reveal_protocol_interface` is incorrect: Expected `type`, found `Literal["foo"]`"

crates/ty_python_semantic/src/types/protocol_class.rs

Lines changed: 89 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use ruff_python_ast::name::Name;
77

88
use super::TypeVarVariance;
99
use crate::semantic_index::place_table;
10+
use crate::types::generics::Specialization;
1011
use crate::{
1112
Db, FxOrderSet,
1213
place::{Boundness, Place, PlaceAndQualifiers, place_from_bindings, place_from_declarations},
@@ -85,6 +86,7 @@ impl<'db> Deref for ProtocolClass<'db> {
8586
pub(super) struct ProtocolInterface<'db> {
8687
#[returns(ref)]
8788
inner: BTreeMap<Name, ProtocolMemberData<'db>>,
89+
specialization: Option<Specialization<'db>>,
8890
}
8991

9092
impl get_size2::GetSize for ProtocolInterface<'_> {}
@@ -128,11 +130,11 @@ impl<'db> ProtocolInterface<'db> {
128130
)
129131
})
130132
.collect();
131-
Self::new(db, members)
133+
Self::new(db, members, None)
132134
}
133135

134136
fn empty(db: &'db dyn Db) -> Self {
135-
Self::new(db, BTreeMap::default())
137+
Self::new(db, BTreeMap::default(), None)
136138
}
137139

138140
pub(super) fn members<'a>(
@@ -142,17 +144,22 @@ impl<'db> ProtocolInterface<'db> {
142144
where
143145
'db: 'a,
144146
{
145-
self.inner(db).iter().map(|(name, data)| ProtocolMember {
146-
name,
147-
kind: data.kind,
148-
qualifiers: data.qualifiers,
149-
})
147+
let specialization = self.specialization(db);
148+
self.inner(db)
149+
.iter()
150+
.map(move |(name, data)| ProtocolMember {
151+
name,
152+
kind: data.kind.apply_optional_specialization(db, specialization),
153+
qualifiers: data.qualifiers,
154+
})
150155
}
151156

152157
fn member_by_name<'a>(self, db: &'db dyn Db, name: &'a str) -> Option<ProtocolMember<'a, 'db>> {
153158
self.inner(db).get(name).map(|data| ProtocolMember {
154159
name,
155-
kind: data.kind,
160+
kind: data
161+
.kind
162+
.apply_optional_specialization(db, self.specialization(db)),
156163
qualifiers: data.qualifiers,
157164
})
158165
}
@@ -186,6 +193,8 @@ impl<'db> ProtocolInterface<'db> {
186193
.iter()
187194
.map(|(name, data)| (name.clone(), data.normalized_impl(db, visitor)))
188195
.collect::<BTreeMap<_, _>>(),
196+
self.specialization(db)
197+
.map(|s| s.normalized_impl(db, visitor)),
189198
)
190199
}
191200

@@ -196,6 +205,7 @@ impl<'db> ProtocolInterface<'db> {
196205
.iter()
197206
.map(|(name, data)| (name.clone(), data.materialize(db, variance)))
198207
.collect::<BTreeMap<_, _>>(),
208+
self.specialization(db).map(|s| s.materialize(db, variance)),
199209
)
200210
}
201211

@@ -204,17 +214,24 @@ impl<'db> ProtocolInterface<'db> {
204214
db: &'db dyn Db,
205215
type_mapping: &TypeMapping<'a, 'db>,
206216
) -> Self {
217+
let mut visitor = TypeTransformer::default();
218+
207219
Self::new(
208220
db,
209221
self.inner(db)
210222
.iter()
211223
.map(|(name, data)| {
212224
(
213225
name.clone(),
214-
data.apply_type_mapping(db, type_mapping).normalized(db),
226+
data.apply_type_mapping(db, type_mapping)
227+
.normalized_impl(db, &mut visitor),
215228
)
216229
})
217230
.collect::<BTreeMap<_, _>>(),
231+
self.specialization(db).map(|s| {
232+
s.apply_type_mapping(db, type_mapping)
233+
.normalized_impl(db, &mut visitor)
234+
}),
218235
)
219236
}
220237

@@ -237,8 +254,13 @@ impl<'db> ProtocolInterface<'db> {
237254
impl std::fmt::Display for ProtocolInterfaceDisplay<'_> {
238255
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
239256
f.write_char('{')?;
240-
for (i, (name, data)) in self.interface.inner(self.db).iter().enumerate() {
241-
write!(f, "\"{name}\": {data}", data = data.display(self.db))?;
257+
for (i, member) in self.interface.members(self.db).enumerate() {
258+
let ProtocolMember {
259+
name,
260+
kind,
261+
qualifiers: _,
262+
} = member;
263+
write!(f, "\"{name}\": {kind}", kind = kind.display(self.db))?;
242264
if i < self.interface.inner(self.db).len() - 1 {
243265
f.write_str(", ")?;
244266
}
@@ -261,10 +283,6 @@ pub(super) struct ProtocolMemberData<'db> {
261283
}
262284

263285
impl<'db> ProtocolMemberData<'db> {
264-
fn normalized(&self, db: &'db dyn Db) -> Self {
265-
self.normalized_impl(db, &mut TypeTransformer::default())
266-
}
267-
268286
fn normalized_impl(&self, db: &'db dyn Db, visitor: &mut TypeTransformer<'db>) -> Self {
269287
Self {
270288
kind: self.kind.normalized_impl(db, visitor),
@@ -293,41 +311,6 @@ impl<'db> ProtocolMemberData<'db> {
293311
qualifiers: self.qualifiers,
294312
}
295313
}
296-
297-
fn display(&self, db: &'db dyn Db) -> impl std::fmt::Display {
298-
struct ProtocolMemberDataDisplay<'db> {
299-
db: &'db dyn Db,
300-
data: ProtocolMemberKind<'db>,
301-
}
302-
303-
impl std::fmt::Display for ProtocolMemberDataDisplay<'_> {
304-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
305-
match self.data {
306-
ProtocolMemberKind::Method(callable) => {
307-
write!(f, "MethodMember(`{}`)", callable.display(self.db))
308-
}
309-
ProtocolMemberKind::Property(property) => {
310-
let mut d = f.debug_struct("PropertyMember");
311-
if let Some(getter) = property.getter(self.db) {
312-
d.field("getter", &format_args!("`{}`", &getter.display(self.db)));
313-
}
314-
if let Some(setter) = property.setter(self.db) {
315-
d.field("setter", &format_args!("`{}`", &setter.display(self.db)));
316-
}
317-
d.finish()
318-
}
319-
ProtocolMemberKind::Other(ty) => {
320-
write!(f, "AttributeMember(`{}`)", ty.display(self.db))
321-
}
322-
}
323-
}
324-
}
325-
326-
ProtocolMemberDataDisplay {
327-
db,
328-
data: self.kind,
329-
}
330-
}
331314
}
332315

333316
#[derive(Debug, Copy, Clone, PartialEq, Eq, salsa::Update, Hash)]
@@ -391,6 +374,59 @@ impl<'db> ProtocolMemberKind<'db> {
391374
}
392375
}
393376
}
377+
378+
fn apply_optional_specialization(
379+
self,
380+
db: &'db dyn Db,
381+
specialization: Option<Specialization<'db>>,
382+
) -> Self {
383+
let Some(specialization) = specialization else {
384+
return self;
385+
};
386+
match self {
387+
ProtocolMemberKind::Method(callable) => ProtocolMemberKind::Method(
388+
callable.apply_type_mapping(db, &TypeMapping::Specialization(specialization)),
389+
),
390+
ProtocolMemberKind::Property(property) => ProtocolMemberKind::Property(
391+
property.apply_type_mapping(db, &TypeMapping::Specialization(specialization)),
392+
),
393+
ProtocolMemberKind::Other(ty) => {
394+
ProtocolMemberKind::Other(ty.apply_specialization(db, specialization))
395+
}
396+
}
397+
}
398+
399+
fn display(self, db: &'db dyn Db) -> impl std::fmt::Display {
400+
struct ProtocolMemberKindDisplay<'db> {
401+
db: &'db dyn Db,
402+
kind: ProtocolMemberKind<'db>,
403+
}
404+
405+
impl std::fmt::Display for ProtocolMemberKindDisplay<'_> {
406+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
407+
match self.kind {
408+
ProtocolMemberKind::Method(callable) => {
409+
write!(f, "MethodMember(`{}`)", callable.display(self.db))
410+
}
411+
ProtocolMemberKind::Property(property) => {
412+
let mut d = f.debug_struct("PropertyMember");
413+
if let Some(getter) = property.getter(self.db) {
414+
d.field("getter", &format_args!("`{}`", &getter.display(self.db)));
415+
}
416+
if let Some(setter) = property.setter(self.db) {
417+
d.field("setter", &format_args!("`{}`", &setter.display(self.db)));
418+
}
419+
d.finish()
420+
}
421+
ProtocolMemberKind::Other(ty) => {
422+
write!(f, "AttributeMember(`{}`)", ty.display(self.db))
423+
}
424+
}
425+
}
426+
}
427+
428+
ProtocolMemberKindDisplay { db, kind: self }
429+
}
394430
}
395431

396432
/// A single member of a protocol interface.
@@ -532,13 +568,10 @@ fn cached_protocol_interface<'db>(
532568
) -> ProtocolInterface<'db> {
533569
let mut members = BTreeMap::default();
534570

535-
for (parent_protocol, specialization) in class
571+
for parent_protocol in class
536572
.iter_mro(db)
537573
.filter_map(ClassBase::into_class)
538-
.filter_map(|class| {
539-
let (class, specialization) = class.class_literal(db);
540-
Some((class.into_protocol_class(db)?, specialization))
541-
})
574+
.filter_map(|class| class.class_literal(db).0.into_protocol_class(db))
542575
{
543576
let parent_scope = parent_protocol.class_literal(db).0.body_scope(db);
544577
let use_def_map = use_def_map(db, parent_scope);
@@ -581,8 +614,6 @@ fn cached_protocol_interface<'db>(
581614
})
582615
.filter(|(name, _, _, _)| !excluded_from_proto_members(name))
583616
.map(|(name, ty, qualifiers, bound_on_class)| {
584-
let ty = ty.apply_optional_specialization(db, specialization);
585-
586617
let kind = match (ty, bound_on_class) {
587618
// TODO: if the getter or setter is a function literal, we should
588619
// upcast it to a `CallableType` so that two protocols with identical property
@@ -607,7 +638,7 @@ fn cached_protocol_interface<'db>(
607638
);
608639
}
609640

610-
ProtocolInterface::new(db, members)
641+
ProtocolInterface::new(db, members, class.class_literal(db).1)
611642
}
612643

613644
#[allow(clippy::trivially_copy_pass_by_ref)]

0 commit comments

Comments
 (0)