@@ -1133,24 +1133,21 @@ impl<'db> Type<'db> {
11331133 }
11341134 }
11351135
1136- /// Promotes any literals within this instance type, or returns the type unchanged if there are
1137- /// no literals to be promoted.
1138- pub ( crate ) fn promote_literals ( self , db : & ' db dyn Db ) -> Type < ' db > {
1136+ /// If this type is a literal, returns a type that would be appropriate as a type annotation for
1137+ /// an instance of the literal.
1138+ ///
1139+ /// Notably, this converts `def _() -> int` to `Callable[[], int]`, which `literal_fallback_instance`
1140+ /// does not.
1141+ pub ( crate ) fn literal_annotation_type ( self , db : & ' db dyn Db ) -> Option < Type < ' db > > {
11391142 match self {
1140- // Promote literals within generic aliases, e.g. `tuple[Literal[1]]` to `tuple[int]`.
1141- Type :: NominalInstance ( instance) => match instance. class ( db) . into_generic_alias ( ) {
1142- Some ( alias) => {
1143- let alias = alias. apply_type_mapping_impl (
1144- db,
1145- & TypeMapping :: PromoteLiterals ,
1146- & ApplyTypeMappingVisitor :: default ( ) ,
1147- ) ;
1148-
1149- Type :: instance ( db, ClassType :: Generic ( alias) )
1150- }
1151- _ => self ,
1152- } ,
1153- _ => self . literal_fallback_instance ( db) . unwrap_or ( self ) ,
1143+ Type :: StringLiteral ( _) | Type :: LiteralString => Some ( KnownClass :: Str . to_instance ( db) ) ,
1144+ Type :: BooleanLiteral ( _) => Some ( KnownClass :: Bool . to_instance ( db) ) ,
1145+ Type :: IntLiteral ( _) => Some ( KnownClass :: Int . to_instance ( db) ) ,
1146+ Type :: BytesLiteral ( _) => Some ( KnownClass :: Bytes . to_instance ( db) ) ,
1147+ Type :: ModuleLiteral ( _) => Some ( KnownClass :: ModuleType . to_instance ( db) ) ,
1148+ Type :: EnumLiteral ( literal) => Some ( literal. enum_class_instance ( db) ) ,
1149+ Type :: FunctionLiteral ( literal) => Some ( Type :: Callable ( literal. into_callable_type ( db) ) ) ,
1150+ _ => None ,
11541151 }
11551152 }
11561153
@@ -6005,8 +6002,10 @@ impl<'db> Type<'db> {
60056002 self
60066003 }
60076004 }
6008- TypeMapping :: PromoteLiterals | TypeMapping :: BindLegacyTypevars ( _) |
6009- TypeMapping :: MarkTypeVarsInferable ( _) => self ,
6005+ TypeMapping :: LiteralToInstance
6006+ | TypeMapping :: LiteralToAnnotation
6007+ | TypeMapping :: BindLegacyTypevars ( _)
6008+ | TypeMapping :: MarkTypeVarsInferable ( _) => self ,
60106009 TypeMapping :: Materialize ( materialization_kind) => {
60116010 Type :: TypeVar ( bound_typevar. materialize_impl ( db, * materialization_kind, visitor) )
60126011 }
@@ -6026,10 +6025,11 @@ impl<'db> Type<'db> {
60266025 self
60276026 }
60286027 }
6029- TypeMapping :: PromoteLiterals |
6030- TypeMapping :: BindLegacyTypevars ( _) |
6031- TypeMapping :: BindSelf ( _) |
6032- TypeMapping :: ReplaceSelf { .. }
6028+ TypeMapping :: LiteralToInstance
6029+ | TypeMapping :: LiteralToAnnotation
6030+ | TypeMapping :: BindLegacyTypevars ( _)
6031+ | TypeMapping :: BindSelf ( _)
6032+ | TypeMapping :: ReplaceSelf { .. }
60336033 => self ,
60346034 TypeMapping :: Materialize ( materialization_kind) => Type :: NonInferableTypeVar ( bound_typevar. materialize_impl ( db, * materialization_kind, visitor) )
60356035
@@ -6041,15 +6041,22 @@ impl<'db> Type<'db> {
60416041 }
60426042 TypeMapping :: Specialization ( _) |
60436043 TypeMapping :: PartialSpecialization ( _) |
6044- TypeMapping :: PromoteLiterals |
6044+ TypeMapping :: LiteralToInstance |
6045+ TypeMapping :: LiteralToAnnotation |
60456046 TypeMapping :: BindSelf ( _) |
60466047 TypeMapping :: ReplaceSelf { .. } |
60476048 TypeMapping :: MarkTypeVarsInferable ( _) |
60486049 TypeMapping :: Materialize ( _) => self ,
60496050 }
60506051
60516052 Type :: FunctionLiteral ( function) => {
6052- Type :: FunctionLiteral ( function. with_type_mapping ( db, type_mapping) )
6053+ let function = Type :: FunctionLiteral ( function. with_type_mapping ( db, type_mapping) ) ;
6054+
6055+ match type_mapping {
6056+ TypeMapping :: LiteralToAnnotation => function. literal_annotation_type ( db)
6057+ . expect ( "function literal should have an annotation type" ) ,
6058+ _ => function
6059+ }
60536060 }
60546061
60556062 Type :: BoundMethod ( method) => Type :: BoundMethod ( BoundMethodType :: new (
@@ -6155,8 +6162,10 @@ impl<'db> Type<'db> {
61556162 TypeMapping :: ReplaceSelf { .. } |
61566163 TypeMapping :: MarkTypeVarsInferable ( _) |
61576164 TypeMapping :: Materialize ( _) => self ,
6158- TypeMapping :: PromoteLiterals => self . literal_fallback_instance ( db)
6165+ TypeMapping :: LiteralToInstance => self . literal_fallback_instance ( db)
61596166 . expect ( "literal type should have fallback instance type" ) ,
6167+ TypeMapping :: LiteralToAnnotation => self . literal_annotation_type ( db)
6168+ . expect ( "literal type should have an annotation type" ) ,
61606169 }
61616170
61626171 Type :: Dynamic ( _) => match type_mapping {
@@ -6166,7 +6175,8 @@ impl<'db> Type<'db> {
61666175 TypeMapping :: BindSelf ( _) |
61676176 TypeMapping :: ReplaceSelf { .. } |
61686177 TypeMapping :: MarkTypeVarsInferable ( _) |
6169- TypeMapping :: PromoteLiterals => self ,
6178+ TypeMapping :: LiteralToInstance => self ,
6179+ TypeMapping :: LiteralToAnnotation => self ,
61706180 TypeMapping :: Materialize ( materialization_kind) => match materialization_kind {
61716181 MaterializationKind :: Top => Type :: object ( ) ,
61726182 MaterializationKind :: Bottom => Type :: Never ,
@@ -6694,7 +6704,10 @@ pub enum TypeMapping<'a, 'db> {
66946704 PartialSpecialization ( PartialSpecialization < ' a , ' db > ) ,
66956705 /// Promotes any literal types to their corresponding instance types (e.g. `Literal["string"]`
66966706 /// to `str`)
6697- PromoteLiterals ,
6707+ LiteralToInstance ,
6708+ /// Promotes any literal types to their corresponding type annotation form (e.g. `Literal["string"]`
6709+ /// to `str`, or `def _() -> int` to `Callable[[], int]`).
6710+ LiteralToAnnotation ,
66986711 /// Binds a legacy typevar with the generic context (class, function, type alias) that it is
66996712 /// being used in.
67006713 BindLegacyTypevars ( BindingContext < ' db > ) ,
@@ -6726,7 +6739,8 @@ fn walk_type_mapping<'db, V: visitor::TypeVisitor<'db> + ?Sized>(
67266739 TypeMapping :: ReplaceSelf { new_upper_bound } => {
67276740 visitor. visit_type ( db, * new_upper_bound) ;
67286741 }
6729- TypeMapping :: PromoteLiterals
6742+ TypeMapping :: LiteralToInstance
6743+ | TypeMapping :: LiteralToAnnotation
67306744 | TypeMapping :: BindLegacyTypevars ( _)
67316745 | TypeMapping :: MarkTypeVarsInferable ( _)
67326746 | TypeMapping :: Materialize ( _) => { }
@@ -6742,7 +6756,8 @@ impl<'db> TypeMapping<'_, 'db> {
67426756 TypeMapping :: PartialSpecialization ( partial) => {
67436757 TypeMapping :: PartialSpecialization ( partial. to_owned ( ) )
67446758 }
6745- TypeMapping :: PromoteLiterals => TypeMapping :: PromoteLiterals ,
6759+ TypeMapping :: LiteralToInstance => TypeMapping :: LiteralToInstance ,
6760+ TypeMapping :: LiteralToAnnotation => TypeMapping :: LiteralToAnnotation ,
67466761 TypeMapping :: BindLegacyTypevars ( binding_context) => {
67476762 TypeMapping :: BindLegacyTypevars ( * binding_context)
67486763 }
@@ -6767,7 +6782,8 @@ impl<'db> TypeMapping<'_, 'db> {
67676782 TypeMapping :: PartialSpecialization ( partial) => {
67686783 TypeMapping :: PartialSpecialization ( partial. normalized_impl ( db, visitor) )
67696784 }
6770- TypeMapping :: PromoteLiterals => TypeMapping :: PromoteLiterals ,
6785+ TypeMapping :: LiteralToInstance => TypeMapping :: LiteralToInstance ,
6786+ TypeMapping :: LiteralToAnnotation => TypeMapping :: LiteralToAnnotation ,
67716787 TypeMapping :: BindLegacyTypevars ( binding_context) => {
67726788 TypeMapping :: BindLegacyTypevars ( * binding_context)
67736789 }
@@ -6795,7 +6811,8 @@ impl<'db> TypeMapping<'_, 'db> {
67956811 match self {
67966812 TypeMapping :: Specialization ( _)
67976813 | TypeMapping :: PartialSpecialization ( _)
6798- | TypeMapping :: PromoteLiterals
6814+ | TypeMapping :: LiteralToInstance
6815+ | TypeMapping :: LiteralToAnnotation
67996816 | TypeMapping :: BindLegacyTypevars ( _)
68006817 | TypeMapping :: MarkTypeVarsInferable ( _)
68016818 | TypeMapping :: Materialize ( _) => context,
0 commit comments