@@ -4821,7 +4821,7 @@ impl<'db> Type<'db> {
4821
4821
pub fn in_type_expression (
4822
4822
& self ,
4823
4823
db : & ' db dyn Db ,
4824
- scope_id : ScopeId ,
4824
+ scope_id : ScopeId < ' db > ,
4825
4825
) -> Result < Type < ' db > , InvalidTypeExpressionError < ' db > > {
4826
4826
match self {
4827
4827
// Special cases for `float` and `complex`
@@ -4872,7 +4872,9 @@ impl<'db> Type<'db> {
4872
4872
| Type :: BoundSuper ( _)
4873
4873
| Type :: ProtocolInstance ( _)
4874
4874
| Type :: PropertyInstance ( _) => Err ( InvalidTypeExpressionError {
4875
- invalid_expressions : smallvec:: smallvec![ InvalidTypeExpression :: InvalidType ( * self ) ] ,
4875
+ invalid_expressions : smallvec:: smallvec![ InvalidTypeExpression :: InvalidType (
4876
+ * self , scope_id
4877
+ ) ] ,
4876
4878
fallback_type : Type :: unknown ( ) ,
4877
4879
} ) ,
4878
4880
@@ -4910,7 +4912,7 @@ impl<'db> Type<'db> {
4910
4912
return Err ( InvalidTypeExpressionError {
4911
4913
fallback_type : Type :: unknown ( ) ,
4912
4914
invalid_expressions : smallvec:: smallvec![
4913
- InvalidTypeExpression :: InvalidType ( * self )
4915
+ InvalidTypeExpression :: InvalidType ( * self , scope_id )
4914
4916
] ,
4915
4917
} ) ;
4916
4918
} ;
@@ -5037,7 +5039,7 @@ impl<'db> Type<'db> {
5037
5039
) ) ,
5038
5040
_ => Err ( InvalidTypeExpressionError {
5039
5041
invalid_expressions : smallvec:: smallvec![ InvalidTypeExpression :: InvalidType (
5040
- * self
5042
+ * self , scope_id
5041
5043
) ] ,
5042
5044
fallback_type : Type :: unknown ( ) ,
5043
5045
} ) ,
@@ -5751,7 +5753,8 @@ impl<'db> InvalidTypeExpressionError<'db> {
5751
5753
let Some ( builder) = context. report_lint ( & INVALID_TYPE_FORM , node) else {
5752
5754
continue ;
5753
5755
} ;
5754
- builder. into_diagnostic ( error. reason ( context. db ( ) ) ) ;
5756
+ let diagnostic = builder. into_diagnostic ( error. reason ( context. db ( ) ) ) ;
5757
+ error. add_subdiagnostics ( context. db ( ) , diagnostic) ;
5755
5758
}
5756
5759
}
5757
5760
fallback_type
@@ -5778,7 +5781,7 @@ enum InvalidTypeExpression<'db> {
5778
5781
/// and which would require exactly one argument even if they appeared in an annotation expression
5779
5782
TypeQualifierRequiresOneArgument ( KnownInstanceType < ' db > ) ,
5780
5783
/// Some types are always invalid in type expressions
5781
- InvalidType ( Type < ' db > ) ,
5784
+ InvalidType ( Type < ' db > , ScopeId < ' db > ) ,
5782
5785
}
5783
5786
5784
5787
impl < ' db > InvalidTypeExpression < ' db > {
@@ -5822,7 +5825,7 @@ impl<'db> InvalidTypeExpression<'db> {
5822
5825
"Type qualifier `{q}` is not allowed in type expressions (only in annotation expressions, and only with exactly one argument)" ,
5823
5826
q = qualifier. repr( self . db)
5824
5827
) ,
5825
- InvalidTypeExpression :: InvalidType ( ty) => write ! (
5828
+ InvalidTypeExpression :: InvalidType ( ty, _ ) => write ! (
5826
5829
f,
5827
5830
"Variable of type `{ty}` is not allowed in a type expression" ,
5828
5831
ty = ty. display( self . db)
@@ -5833,6 +5836,38 @@ impl<'db> InvalidTypeExpression<'db> {
5833
5836
5834
5837
Display { error : self , db }
5835
5838
}
5839
+
5840
+ fn add_subdiagnostics ( self , db : & ' db dyn Db , mut diagnostic : LintDiagnosticGuard ) {
5841
+ let InvalidTypeExpression :: InvalidType ( ty, scope) = self else {
5842
+ return ;
5843
+ } ;
5844
+ let Type :: ModuleLiteral ( module_type) = ty else {
5845
+ return ;
5846
+ } ;
5847
+ let module = module_type. module ( db) ;
5848
+ let Some ( module_name_final_part) = module. name ( ) . components ( ) . next_back ( ) else {
5849
+ return ;
5850
+ } ;
5851
+ let Some ( module_member_with_same_name) = ty
5852
+ . member ( db, module_name_final_part)
5853
+ . symbol
5854
+ . ignore_possibly_unbound ( )
5855
+ else {
5856
+ return ;
5857
+ } ;
5858
+ if module_member_with_same_name
5859
+ . in_type_expression ( db, scope)
5860
+ . is_err ( )
5861
+ {
5862
+ return ;
5863
+ }
5864
+
5865
+ // TODO: showing a diff (and even having an autofix) would be even better
5866
+ diagnostic. info ( format_args ! (
5867
+ "Did you mean to use the module's member \
5868
+ `{module_name_final_part}.{module_name_final_part}` instead?"
5869
+ ) ) ;
5870
+ }
5836
5871
}
5837
5872
5838
5873
/// Whether this typecar was created via the legacy `TypeVar` constructor, or using PEP 695 syntax.
0 commit comments