@@ -7,6 +7,7 @@ use ruff_python_ast::name::Name;
77
88use super :: TypeVarVariance ;
99use crate :: semantic_index:: place_table;
10+ use crate :: types:: generics:: Specialization ;
1011use 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> {
8586pub ( super ) struct ProtocolInterface < ' db > {
8687 #[ returns( ref) ]
8788 inner : BTreeMap < Name , ProtocolMemberData < ' db > > ,
89+ specialization : Option < Specialization < ' db > > ,
8890}
8991
9092impl 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
263285impl < ' 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