@@ -2470,32 +2470,45 @@ impl<'db> Type<'db> {
2470
2470
match self {
2471
2471
// Special cases for `float` and `complex`
2472
2472
// 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)
2495
2493
}
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
+
2499
2512
// We treat `typing.Type` exactly the same as `builtins.type`:
2500
2513
Type :: KnownInstance ( KnownInstanceType :: Type ) => Ok ( KnownClass :: Type . to_instance ( db) ) ,
2501
2514
Type :: KnownInstance ( KnownInstanceType :: Tuple ) => Ok ( KnownClass :: Tuple . to_instance ( db) ) ,
@@ -2580,9 +2593,13 @@ impl<'db> Type<'db> {
2580
2593
Type :: KnownInstance ( KnownInstanceType :: Unknown ) => Ok ( Type :: unknown ( ) ) ,
2581
2594
Type :: KnownInstance ( KnownInstanceType :: AlwaysTruthy ) => Ok ( Type :: AlwaysTruthy ) ,
2582
2595
Type :: KnownInstance ( KnownInstanceType :: AlwaysFalsy ) => Ok ( Type :: AlwaysFalsy ) ,
2583
- _ => Ok ( todo_type ! (
2584
- "Unsupported or invalid type in a type expression"
2596
+ Type :: Instance ( _) => Ok ( todo_type ! (
2597
+ "Invalid or unsupported `Instance` in `Type::to_type_expression`"
2598
+ ) ) ,
2599
+ Type :: KnownInstance ( _) => Ok ( todo_type ! (
2600
+ "Invalid or unsupported `KnownInstanceType` in `Type::to_type_expression`"
2585
2601
) ) ,
2602
+ Type :: Intersection ( _) => Ok ( todo_type ! ( "Type::Intersection.in_type_expression" ) ) ,
2586
2603
}
2587
2604
}
2588
2605
@@ -2815,7 +2832,7 @@ impl<'db> From<Type<'db>> for TypeAndQualifiers<'db> {
2815
2832
#[ derive( Debug , PartialEq , Eq ) ]
2816
2833
pub struct InvalidTypeExpressionError < ' db > {
2817
2834
fallback_type : Type < ' db > ,
2818
- invalid_expressions : smallvec:: SmallVec < [ InvalidTypeExpression ; 1 ] > ,
2835
+ invalid_expressions : smallvec:: SmallVec < [ InvalidTypeExpression < ' db > ; 1 ] > ,
2819
2836
}
2820
2837
2821
2838
impl < ' db > InvalidTypeExpressionError < ' db > {
@@ -2825,15 +2842,19 @@ impl<'db> InvalidTypeExpressionError<'db> {
2825
2842
invalid_expressions,
2826
2843
} = self ;
2827
2844
for error in invalid_expressions {
2828
- context. report_lint ( & INVALID_TYPE_FORM , node, format_args ! ( "{}" , error. reason( ) ) ) ;
2845
+ context. report_lint (
2846
+ & INVALID_TYPE_FORM ,
2847
+ node,
2848
+ format_args ! ( "{}" , error. reason( context. db( ) ) ) ,
2849
+ ) ;
2829
2850
}
2830
2851
fallback_type
2831
2852
}
2832
2853
}
2833
2854
2834
2855
/// Enumeration of various types that are invalid in type-expression contexts
2835
2856
#[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
2836
- enum InvalidTypeExpression {
2857
+ enum InvalidTypeExpression < ' db > {
2837
2858
/// `x: Annotated` is invalid as an annotation
2838
2859
BareAnnotated ,
2839
2860
/// `x: Literal` is invalid as an annotation
@@ -2842,16 +2863,42 @@ enum InvalidTypeExpression {
2842
2863
ClassVarInTypeExpression ,
2843
2864
/// The `Final` type qualifier was used in a type expression
2844
2865
FinalInTypeExpression ,
2866
+ /// Some types are always invalid in type expressions
2867
+ InvalidType ( Type < ' db > ) ,
2845
2868
}
2846
2869
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)" ,
2870
+ impl < ' db > InvalidTypeExpression < ' db > {
2871
+ const fn reason ( self , db : & ' db dyn Db ) -> impl std:: fmt:: Display + ' db {
2872
+ struct Display < ' db > {
2873
+ error : InvalidTypeExpression < ' db > ,
2874
+ db : & ' db dyn Db ,
2854
2875
}
2876
+
2877
+ impl std:: fmt:: Display for Display < ' _ > {
2878
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
2879
+ match self . error {
2880
+ InvalidTypeExpression :: BareAnnotated => f. write_str (
2881
+ "`Annotated` requires at least two arguments when used in an annotation or type expression"
2882
+ ) ,
2883
+ InvalidTypeExpression :: BareLiteral => f. write_str (
2884
+ "`Literal` requires at least one argument when used in a type expression"
2885
+ ) ,
2886
+ InvalidTypeExpression :: ClassVarInTypeExpression => f. write_str (
2887
+ "Type qualifier `typing.ClassVar` is not allowed in type expressions (only in annotation expressions)"
2888
+ ) ,
2889
+ InvalidTypeExpression :: FinalInTypeExpression => f. write_str (
2890
+ "Type qualifier `typing.Final` is not allowed in type expressions (only in annotation expressions)"
2891
+ ) ,
2892
+ InvalidTypeExpression :: InvalidType ( ty) => write ! (
2893
+ f,
2894
+ "Variable of type `{ty}` is not allowed in a type expression" ,
2895
+ ty = ty. display( self . db)
2896
+ ) ,
2897
+ }
2898
+ }
2899
+ }
2900
+
2901
+ Display { error : self , db }
2855
2902
}
2856
2903
}
2857
2904
0 commit comments