@@ -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) ) ,
@@ -2556,7 +2569,6 @@ impl<'db> Type<'db> {
2556
2569
}
2557
2570
Type :: KnownInstance ( KnownInstanceType :: LiteralString ) => Ok ( Type :: LiteralString ) ,
2558
2571
Type :: KnownInstance ( KnownInstanceType :: Any ) => Ok ( Type :: any ( ) ) ,
2559
- // TODO: Should emit a diagnostic
2560
2572
Type :: KnownInstance ( KnownInstanceType :: Annotated ) => Err ( InvalidTypeExpressionError {
2561
2573
invalid_expressions : smallvec:: smallvec![ InvalidTypeExpression :: BareAnnotated ] ,
2562
2574
fallback_type : Type :: unknown ( ) ,
@@ -2580,9 +2592,13 @@ impl<'db> Type<'db> {
2580
2592
Type :: KnownInstance ( KnownInstanceType :: Unknown ) => Ok ( Type :: unknown ( ) ) ,
2581
2593
Type :: KnownInstance ( KnownInstanceType :: AlwaysTruthy ) => Ok ( Type :: AlwaysTruthy ) ,
2582
2594
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`"
2585
2600
) ) ,
2601
+ Type :: Intersection ( _) => Ok ( todo_type ! ( "Type::Intersection.in_type_expression" ) ) ,
2586
2602
}
2587
2603
}
2588
2604
@@ -2815,7 +2831,7 @@ impl<'db> From<Type<'db>> for TypeAndQualifiers<'db> {
2815
2831
#[ derive( Debug , PartialEq , Eq ) ]
2816
2832
pub struct InvalidTypeExpressionError < ' db > {
2817
2833
fallback_type : Type < ' db > ,
2818
- invalid_expressions : smallvec:: SmallVec < [ InvalidTypeExpression ; 1 ] > ,
2834
+ invalid_expressions : smallvec:: SmallVec < [ InvalidTypeExpression < ' db > ; 1 ] > ,
2819
2835
}
2820
2836
2821
2837
impl < ' db > InvalidTypeExpressionError < ' db > {
@@ -2825,15 +2841,19 @@ impl<'db> InvalidTypeExpressionError<'db> {
2825
2841
invalid_expressions,
2826
2842
} = self ;
2827
2843
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
+ ) ;
2829
2849
}
2830
2850
fallback_type
2831
2851
}
2832
2852
}
2833
2853
2834
2854
/// Enumeration of various types that are invalid in type-expression contexts
2835
2855
#[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
2836
- enum InvalidTypeExpression {
2856
+ enum InvalidTypeExpression < ' db > {
2837
2857
/// `x: Annotated` is invalid as an annotation
2838
2858
BareAnnotated ,
2839
2859
/// `x: Literal` is invalid as an annotation
@@ -2842,16 +2862,42 @@ enum InvalidTypeExpression {
2842
2862
ClassVarInTypeExpression ,
2843
2863
/// The `Final` type qualifier was used in a type expression
2844
2864
FinalInTypeExpression ,
2865
+ /// Some types are always invalid in type expressions
2866
+ InvalidType ( Type < ' db > ) ,
2845
2867
}
2846
2868
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 ,
2854
2874
}
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 }
2855
2901
}
2856
2902
}
2857
2903
0 commit comments