@@ -2470,32 +2470,47 @@ 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 :: DynamicVariable (
2509+ * self
2510+ ) ] ,
2511+ fallback_type : Type :: unknown ( ) ,
2512+ } ) ,
2513+
24992514 // We treat `typing.Type` exactly the same as `builtins.type`:
25002515 Type :: KnownInstance ( KnownInstanceType :: Type ) => Ok ( KnownClass :: Type . to_instance ( db) ) ,
25012516 Type :: KnownInstance ( KnownInstanceType :: Tuple ) => Ok ( KnownClass :: Tuple . to_instance ( db) ) ,
@@ -2580,9 +2595,13 @@ impl<'db> Type<'db> {
25802595 Type :: KnownInstance ( KnownInstanceType :: Unknown ) => Ok ( Type :: unknown ( ) ) ,
25812596 Type :: KnownInstance ( KnownInstanceType :: AlwaysTruthy ) => Ok ( Type :: AlwaysTruthy ) ,
25822597 Type :: KnownInstance ( KnownInstanceType :: AlwaysFalsy ) => Ok ( Type :: AlwaysFalsy ) ,
2583- _ => Ok ( todo_type ! (
2584- "Unsupported or invalid type in a type expression"
2598+ Type :: Instance ( _) => Ok ( todo_type ! (
2599+ "Invalid or unsupported `Instance` in `Type::to_type_expression()`"
2600+ ) ) ,
2601+ Type :: KnownInstance ( _) => Ok ( todo_type ! (
2602+ "Invalid or unsupported `KnownInstanceType` in `Type::to_type_expression()`"
25852603 ) ) ,
2604+ Type :: Intersection ( _) => Ok ( todo_type ! ( "Type::Intersection.in_type_expression()" ) ) ,
25862605 }
25872606 }
25882607
@@ -2815,7 +2834,7 @@ impl<'db> From<Type<'db>> for TypeAndQualifiers<'db> {
28152834#[ derive( Debug , PartialEq , Eq ) ]
28162835pub struct InvalidTypeExpressionError < ' db > {
28172836 fallback_type : Type < ' db > ,
2818- invalid_expressions : smallvec:: SmallVec < [ InvalidTypeExpression ; 1 ] > ,
2837+ invalid_expressions : smallvec:: SmallVec < [ InvalidTypeExpression < ' db > ; 1 ] > ,
28192838}
28202839
28212840impl < ' db > InvalidTypeExpressionError < ' db > {
@@ -2825,15 +2844,19 @@ impl<'db> InvalidTypeExpressionError<'db> {
28252844 invalid_expressions,
28262845 } = self ;
28272846 for error in invalid_expressions {
2828- context. report_lint ( & INVALID_TYPE_FORM , node, format_args ! ( "{}" , error. reason( ) ) ) ;
2847+ context. report_lint (
2848+ & INVALID_TYPE_FORM ,
2849+ node,
2850+ format_args ! ( "{}" , error. reason( context. db( ) ) ) ,
2851+ ) ;
28292852 }
28302853 fallback_type
28312854 }
28322855}
28332856
28342857/// Enumeration of various types that are invalid in type-expression contexts
28352858#[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
2836- enum InvalidTypeExpression {
2859+ enum InvalidTypeExpression < ' db > {
28372860 /// `x: Annotated` is invalid as an annotation
28382861 BareAnnotated ,
28392862 /// `x: Literal` is invalid as an annotation
@@ -2842,16 +2865,42 @@ enum InvalidTypeExpression {
28422865 ClassVarInTypeExpression ,
28432866 /// The `Final` type qualifier was used in a type expression
28442867 FinalInTypeExpression ,
2868+ /// Dynamic variables are not allowed in type expressions
2869+ DynamicVariable ( Type < ' db > ) ,
28452870}
28462871
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)" ,
2872+ impl < ' db > InvalidTypeExpression < ' db > {
2873+ const fn reason ( self , db : & ' db dyn Db ) -> impl std:: fmt:: Display + ' db {
2874+ struct Display < ' db > {
2875+ error : InvalidTypeExpression < ' db > ,
2876+ db : & ' db dyn Db ,
28542877 }
2878+
2879+ impl std:: fmt:: Display for Display < ' _ > {
2880+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
2881+ match self . error {
2882+ InvalidTypeExpression :: BareAnnotated => f. write_str (
2883+ "`Annotated` requires at least two arguments when used in an annotation or type expression"
2884+ ) ,
2885+ InvalidTypeExpression :: BareLiteral => f. write_str (
2886+ "`Literal` requires at least one argument when used in a type expression"
2887+ ) ,
2888+ InvalidTypeExpression :: ClassVarInTypeExpression => f. write_str (
2889+ "Type qualifier `typing.ClassVar` is not allowed in type expressions (only in annotation expressions)"
2890+ ) ,
2891+ InvalidTypeExpression :: FinalInTypeExpression => f. write_str (
2892+ "Type qualifier `typing.Final` is not allowed in type expressions (only in annotation expressions)"
2893+ ) ,
2894+ InvalidTypeExpression :: DynamicVariable ( ty) => write ! (
2895+ f,
2896+ "Dynamic variable of type `{ty}` is not allowed in type expressions" ,
2897+ ty = ty. display( self . db)
2898+ ) ,
2899+ }
2900+ }
2901+ }
2902+
2903+ Display { error : self , db }
28552904 }
28562905}
28572906
0 commit comments