@@ -2470,32 +2470,45 @@ impl<'db> Type<'db> {
24702470 match self {
24712471 // Special cases for `float` and `complex`
24722472 // https://typing.readthedocs.io/en/latest/spec/special-types.html#special-cases-for-float-and-complex
2473- Type :: ClassLiteral ( ClassLiteralType { class } )
2474- if class. is_known ( db, KnownClass :: Float ) =>
2475- {
2476- Ok ( UnionType :: from_elements (
2477- db,
2478- [
2479- KnownClass :: Int . to_instance ( db) ,
2480- KnownClass :: Float . to_instance ( db) ,
2481- ] ,
2482- ) )
2483- }
2484- Type :: ClassLiteral ( ClassLiteralType { class } )
2485- if class. is_known ( db, KnownClass :: Complex ) =>
2486- {
2487- Ok ( UnionType :: from_elements (
2488- db,
2489- [
2490- KnownClass :: Int . to_instance ( db) ,
2491- KnownClass :: Float . to_instance ( db) ,
2492- KnownClass :: Complex . to_instance ( db) ,
2493- ] ,
2494- ) )
2473+ Type :: ClassLiteral ( ClassLiteralType { class } ) => {
2474+ let ty = match class. known ( db) {
2475+ Some ( KnownClass :: Complex ) => UnionType :: from_elements (
2476+ db,
2477+ [
2478+ KnownClass :: Int . to_instance ( db) ,
2479+ KnownClass :: Float . to_instance ( db) ,
2480+ KnownClass :: Complex . to_instance ( db) ,
2481+ ] ,
2482+ ) ,
2483+ Some ( KnownClass :: Float ) => UnionType :: from_elements (
2484+ db,
2485+ [
2486+ KnownClass :: Int . to_instance ( db) ,
2487+ KnownClass :: Float . to_instance ( db) ,
2488+ ] ,
2489+ ) ,
2490+ _ => Type :: instance ( * class) ,
2491+ } ;
2492+ Ok ( ty)
24952493 }
2496- // In a type expression, a bare `type` is interpreted as "instance of `type`", which is
2497- // equivalent to `type[object]`.
2498- Type :: ClassLiteral ( _) | Type :: SubclassOf ( _) => Ok ( self . to_instance ( db) ) ,
2494+ Type :: SubclassOf ( _)
2495+ | Type :: BooleanLiteral ( _)
2496+ | Type :: BytesLiteral ( _)
2497+ | Type :: AlwaysTruthy
2498+ | Type :: AlwaysFalsy
2499+ | Type :: SliceLiteral ( _)
2500+ | Type :: IntLiteral ( _)
2501+ | Type :: LiteralString
2502+ | Type :: ModuleLiteral ( _)
2503+ | Type :: StringLiteral ( _)
2504+ | Type :: Tuple ( _)
2505+ | Type :: Callable ( _)
2506+ | Type :: Never
2507+ | Type :: FunctionLiteral ( _) => Err ( InvalidTypeExpressionError {
2508+ invalid_expressions : smallvec:: smallvec![ InvalidTypeExpression :: InvalidType ( * self ) ] ,
2509+ fallback_type : Type :: unknown ( ) ,
2510+ } ) ,
2511+
24992512 // We treat `typing.Type` exactly the same as `builtins.type`:
25002513 Type :: KnownInstance ( KnownInstanceType :: Type ) => Ok ( KnownClass :: Type . to_instance ( db) ) ,
25012514 Type :: KnownInstance ( KnownInstanceType :: Tuple ) => Ok ( KnownClass :: Tuple . to_instance ( db) ) ,
@@ -2556,7 +2569,6 @@ impl<'db> Type<'db> {
25562569 }
25572570 Type :: KnownInstance ( KnownInstanceType :: LiteralString ) => Ok ( Type :: LiteralString ) ,
25582571 Type :: KnownInstance ( KnownInstanceType :: Any ) => Ok ( Type :: any ( ) ) ,
2559- // TODO: Should emit a diagnostic
25602572 Type :: KnownInstance ( KnownInstanceType :: Annotated ) => Err ( InvalidTypeExpressionError {
25612573 invalid_expressions : smallvec:: smallvec![ InvalidTypeExpression :: BareAnnotated ] ,
25622574 fallback_type : Type :: unknown ( ) ,
@@ -2580,9 +2592,13 @@ impl<'db> Type<'db> {
25802592 Type :: KnownInstance ( KnownInstanceType :: Unknown ) => Ok ( Type :: unknown ( ) ) ,
25812593 Type :: KnownInstance ( KnownInstanceType :: AlwaysTruthy ) => Ok ( Type :: AlwaysTruthy ) ,
25822594 Type :: KnownInstance ( KnownInstanceType :: AlwaysFalsy ) => Ok ( Type :: AlwaysFalsy ) ,
2583- _ => Ok ( todo_type ! (
2584- "Unsupported or invalid type in a type expression"
2595+ Type :: KnownInstance ( _) => Ok ( todo_type ! (
2596+ "Invalid or unsupported `KnownInstanceType` in `Type::to_type_expression`"
2597+ ) ) ,
2598+ Type :: Instance ( _) => Ok ( todo_type ! (
2599+ "Invalid or unsupported `Instance` in `Type::to_type_expression`"
25852600 ) ) ,
2601+ Type :: Intersection ( _) => Ok ( todo_type ! ( "Type::Intersection.in_type_expression" ) ) ,
25862602 }
25872603 }
25882604
@@ -2815,7 +2831,7 @@ impl<'db> From<Type<'db>> for TypeAndQualifiers<'db> {
28152831#[ derive( Debug , PartialEq , Eq ) ]
28162832pub struct InvalidTypeExpressionError < ' db > {
28172833 fallback_type : Type < ' db > ,
2818- invalid_expressions : smallvec:: SmallVec < [ InvalidTypeExpression ; 1 ] > ,
2834+ invalid_expressions : smallvec:: SmallVec < [ InvalidTypeExpression < ' db > ; 1 ] > ,
28192835}
28202836
28212837impl < ' db > InvalidTypeExpressionError < ' db > {
@@ -2825,15 +2841,19 @@ impl<'db> InvalidTypeExpressionError<'db> {
28252841 invalid_expressions,
28262842 } = self ;
28272843 for error in invalid_expressions {
2828- context. report_lint ( & INVALID_TYPE_FORM , node, format_args ! ( "{}" , error. reason( ) ) ) ;
2844+ context. report_lint (
2845+ & INVALID_TYPE_FORM ,
2846+ node,
2847+ format_args ! ( "{}" , error. reason( context. db( ) ) ) ,
2848+ ) ;
28292849 }
28302850 fallback_type
28312851 }
28322852}
28332853
28342854/// Enumeration of various types that are invalid in type-expression contexts
28352855#[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
2836- enum InvalidTypeExpression {
2856+ enum InvalidTypeExpression < ' db > {
28372857 /// `x: Annotated` is invalid as an annotation
28382858 BareAnnotated ,
28392859 /// `x: Literal` is invalid as an annotation
@@ -2842,16 +2862,42 @@ enum InvalidTypeExpression {
28422862 ClassVarInTypeExpression ,
28432863 /// The `Final` type qualifier was used in a type expression
28442864 FinalInTypeExpression ,
2865+ /// Some types are always invalid in type expressions
2866+ InvalidType ( Type < ' db > ) ,
28452867}
28462868
2847- impl InvalidTypeExpression {
2848- const fn reason ( self ) -> & ' static str {
2849- match self {
2850- Self :: BareAnnotated => "`Annotated` requires at least two arguments when used in an annotation or type expression" ,
2851- Self :: BareLiteral => "`Literal` requires at least one argument when used in a type expression" ,
2852- Self :: ClassVarInTypeExpression => "Type qualifier `typing.ClassVar` is not allowed in type expressions (only in annotation expressions)" ,
2853- Self :: FinalInTypeExpression => "Type qualifier `typing.Final` is not allowed in type expressions (only in annotation expressions)" ,
2869+ impl < ' db > InvalidTypeExpression < ' db > {
2870+ const fn reason ( self , db : & ' db dyn Db ) -> impl std:: fmt:: Display + ' db {
2871+ struct Display < ' db > {
2872+ error : InvalidTypeExpression < ' db > ,
2873+ db : & ' db dyn Db ,
28542874 }
2875+
2876+ impl std:: fmt:: Display for Display < ' _ > {
2877+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
2878+ match self . error {
2879+ InvalidTypeExpression :: BareAnnotated => f. write_str (
2880+ "`Annotated` requires at least two arguments when used in an annotation or type expression"
2881+ ) ,
2882+ InvalidTypeExpression :: BareLiteral => f. write_str (
2883+ "`Literal` requires at least one argument when used in a type expression"
2884+ ) ,
2885+ InvalidTypeExpression :: ClassVarInTypeExpression => f. write_str (
2886+ "Type qualifier `typing.ClassVar` is not allowed in type expressions (only in annotation expressions)"
2887+ ) ,
2888+ InvalidTypeExpression :: FinalInTypeExpression => f. write_str (
2889+ "Type qualifier `typing.Final` is not allowed in type expressions (only in annotation expressions)"
2890+ ) ,
2891+ InvalidTypeExpression :: InvalidType ( ty) => write ! (
2892+ f,
2893+ "Variable of type `{ty}` is not allowed in a type expression" ,
2894+ ty = ty. display( self . db)
2895+ ) ,
2896+ }
2897+ }
2898+ }
2899+
2900+ Display { error : self , db }
28552901 }
28562902}
28572903
0 commit comments