@@ -5661,13 +5661,25 @@ impl<'db> Type<'db> {
56615661 ] ,
56625662 } ) ;
56635663 } ;
5664- let instance = Type :: instance ( db, class. unknown_specialization ( db) ) ;
5664+
5665+ let upper_bound = Type :: instance (
5666+ db,
5667+ class. apply_specialization ( db, |generic_context| {
5668+ let types = generic_context
5669+ . variables ( db)
5670+ . iter ( )
5671+ . map ( |typevar| Type :: NonInferableTypeVar ( * typevar) ) ;
5672+
5673+ generic_context. specialize ( db, types. collect ( ) )
5674+ } ) ,
5675+ ) ;
5676+
56655677 let class_definition = class. definition ( db) ;
56665678 let typevar = TypeVarInstance :: new (
56675679 db,
56685680 ast:: name:: Name :: new_static ( "Self" ) ,
56695681 Some ( class_definition) ,
5670- Some ( TypeVarBoundOrConstraints :: UpperBound ( instance ) . into ( ) ) ,
5682+ Some ( TypeVarBoundOrConstraints :: UpperBound ( upper_bound ) . into ( ) ) ,
56715683 // According to the [spec], we can consider `Self`
56725684 // equivalent to an invariant type variable
56735685 // [spec]: https://typing.python.org/en/latest/spec/generics.html#self
@@ -6009,8 +6021,8 @@ impl<'db> Type<'db> {
60096021 partial. get ( db, bound_typevar) . unwrap_or ( self )
60106022 }
60116023 TypeMapping :: MarkTypeVarsInferable ( binding_context) => {
6012- if bound_typevar . binding_context ( db ) == * binding_context {
6013- Type :: TypeVar ( bound_typevar)
6024+ if binding_context. is_none_or ( |context| context == bound_typevar . binding_context ( db ) ) {
6025+ Type :: TypeVar ( bound_typevar. mark_typevars_inferable ( db , visitor ) )
60146026 } else {
60156027 self
60166028 }
@@ -6695,7 +6707,7 @@ pub enum TypeMapping<'a, 'db> {
66956707 /// Replaces occurrences of `typing.Self` with a new `Self` type variable with the given upper bound.
66966708 ReplaceSelf { new_upper_bound : Type < ' db > } ,
66976709 /// Marks the typevars that are bound by a generic class or function as inferable.
6698- MarkTypeVarsInferable ( BindingContext < ' db > ) ,
6710+ MarkTypeVarsInferable ( Option < BindingContext < ' db > > ) ,
66996711 /// Create the top or bottom materialization of a type.
67006712 Materialize ( MaterializationKind ) ,
67016713}
@@ -7636,6 +7648,42 @@ impl<'db> TypeVarInstance<'db> {
76367648 )
76377649 }
76387650
7651+ fn mark_typevars_inferable < ' a > (
7652+ self ,
7653+ db : & ' db dyn Db ,
7654+ visitor : & ApplyTypeMappingVisitor < ' db > ,
7655+ ) -> Self {
7656+ let type_mapping = & TypeMapping :: MarkTypeVarsInferable ( None ) ;
7657+
7658+ Self :: new (
7659+ db,
7660+ self . name ( db) ,
7661+ self . definition ( db) ,
7662+ self . _bound_or_constraints ( db)
7663+ . and_then ( |bound_or_constraints| match bound_or_constraints {
7664+ TypeVarBoundOrConstraintsEvaluation :: Eager ( bound_or_constraints) => Some (
7665+ bound_or_constraints
7666+ . mark_typevars_inferable ( db, type_mapping, visitor)
7667+ . into ( ) ,
7668+ ) ,
7669+ TypeVarBoundOrConstraintsEvaluation :: LazyUpperBound
7670+ | TypeVarBoundOrConstraintsEvaluation :: LazyConstraints => {
7671+ Some ( bound_or_constraints)
7672+ }
7673+ } ) ,
7674+ self . explicit_variance ( db) ,
7675+ self . _default ( db) . and_then ( |default| match default {
7676+ TypeVarDefaultEvaluation :: Eager ( ty) => {
7677+ Some ( ty. apply_type_mapping_impl ( db, type_mapping, visitor) . into ( ) )
7678+ }
7679+ TypeVarDefaultEvaluation :: Lazy => self
7680+ . lazy_default ( db)
7681+ . map ( |ty| ty. apply_type_mapping_impl ( db, type_mapping, visitor) . into ( ) ) ,
7682+ } ) ,
7683+ self . kind ( db) ,
7684+ )
7685+ }
7686+
76397687 fn to_instance ( self , db : & ' db dyn Db ) -> Option < Self > {
76407688 let bound_or_constraints = match self . bound_or_constraints ( db) ? {
76417689 TypeVarBoundOrConstraints :: UpperBound ( upper_bound) => {
@@ -7866,6 +7914,18 @@ impl<'db> BoundTypeVarInstance<'db> {
78667914 )
78677915 }
78687916
7917+ fn mark_typevars_inferable < ' a > (
7918+ self ,
7919+ db : & ' db dyn Db ,
7920+ visitor : & ApplyTypeMappingVisitor < ' db > ,
7921+ ) -> Self {
7922+ Self :: new (
7923+ db,
7924+ self . typevar ( db) . mark_typevars_inferable ( db, visitor) ,
7925+ self . binding_context ( db) ,
7926+ )
7927+ }
7928+
78697929 fn to_instance ( self , db : & ' db dyn Db ) -> Option < Self > {
78707930 Some ( Self :: new (
78717931 db,
@@ -7971,6 +8031,30 @@ impl<'db> TypeVarBoundOrConstraints<'db> {
79718031 }
79728032 }
79738033 }
8034+
8035+ fn mark_typevars_inferable < ' a > (
8036+ self ,
8037+ db : & ' db dyn Db ,
8038+ type_mapping : & TypeMapping < ' a , ' db > ,
8039+ visitor : & ApplyTypeMappingVisitor < ' db > ,
8040+ ) -> Self {
8041+ match self {
8042+ TypeVarBoundOrConstraints :: UpperBound ( bound) => TypeVarBoundOrConstraints :: UpperBound (
8043+ bound. apply_type_mapping_impl ( db, type_mapping, visitor) ,
8044+ ) ,
8045+ TypeVarBoundOrConstraints :: Constraints ( constraints) => {
8046+ TypeVarBoundOrConstraints :: Constraints ( UnionType :: new (
8047+ db,
8048+ constraints
8049+ . elements ( db)
8050+ . iter ( )
8051+ . map ( |ty| ty. apply_type_mapping_impl ( db, type_mapping, visitor) )
8052+ . collect :: < Vec < _ > > ( )
8053+ . into_boxed_slice ( ) ,
8054+ ) )
8055+ }
8056+ }
8057+ }
79748058}
79758059
79768060/// Error returned if a type is not awaitable.
0 commit comments