@@ -65,7 +65,7 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
6565 fn report_invalid_type_expression (
6666 & self ,
6767 expression : & ast:: Expr ,
68- message : std:: fmt:: Arguments ,
68+ message : impl std:: fmt:: Display ,
6969 ) -> Option < LintDiagnosticGuard < ' _ , ' _ > > {
7070 self . context
7171 . report_lint ( & INVALID_TYPE_FORM , expression)
@@ -1292,26 +1292,53 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
12921292
12931293 let return_type = arguments. next ( ) . map ( |arg| self . infer_type_expression ( arg) ) ;
12941294
1295- let correct_argument_number = if let Some ( third_argument) = arguments. next ( ) {
1296- self . infer_type_expression ( third_argument) ;
1297- for argument in arguments {
1298- self . infer_type_expression ( argument) ;
1295+ let callable_type = if parameters. is_none ( )
1296+ && let Some ( first_argument) = first_argument
1297+ && let ast:: Expr :: List ( list) = first_argument
1298+ && let [ single_param] = & list. elts [ ..]
1299+ && single_param. is_ellipsis_literal_expr ( )
1300+ {
1301+ self . store_expression_type ( single_param, Type :: unknown ( ) ) ;
1302+ if let Some ( mut diagnostic) = self . report_invalid_type_expression (
1303+ first_argument,
1304+ "`[...]` is not a valid parameter list for `Callable`" ,
1305+ ) {
1306+ if let Some ( returns) = return_type {
1307+ diagnostic. set_primary_message ( format_args ! (
1308+ "Did you mean `Callable[..., {}]`?" ,
1309+ returns. display( db)
1310+ ) ) ;
1311+ }
12991312 }
1300- false
1313+ Type :: single_callable (
1314+ db,
1315+ Signature :: new (
1316+ Parameters :: unknown ( ) ,
1317+ return_type. unwrap_or_else ( Type :: unknown) ,
1318+ ) ,
1319+ )
13011320 } else {
1302- return_type. is_some ( )
1303- } ;
1321+ let correct_argument_number = if let Some ( third_argument) = arguments. next ( ) {
1322+ self . infer_type_expression ( third_argument) ;
1323+ for argument in arguments {
1324+ self . infer_type_expression ( argument) ;
1325+ }
1326+ false
1327+ } else {
1328+ return_type. is_some ( )
1329+ } ;
13041330
1305- if !correct_argument_number {
1306- report_invalid_arguments_to_callable ( & self . context , subscript) ;
1307- }
1331+ if !correct_argument_number {
1332+ report_invalid_arguments_to_callable ( & self . context , subscript) ;
1333+ }
13081334
1309- let callable_type = if let ( Some ( parameters) , Some ( return_type) , true ) =
1310- ( parameters, return_type, correct_argument_number)
1311- {
1312- Type :: single_callable ( db, Signature :: new ( parameters, return_type) )
1313- } else {
1314- Type :: Callable ( CallableType :: unknown ( db) )
1335+ if correct_argument_number
1336+ && let ( Some ( parameters) , Some ( return_type) ) = ( parameters, return_type)
1337+ {
1338+ Type :: single_callable ( db, Signature :: new ( parameters, return_type) )
1339+ } else {
1340+ Type :: Callable ( CallableType :: unknown ( db) )
1341+ }
13151342 } ;
13161343
13171344 // `Signature` / `Parameters` are not a `Type` variant, so we're storing
@@ -1863,35 +1890,25 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
18631890 return Some ( Parameters :: gradual_form ( ) ) ;
18641891 }
18651892 ast:: Expr :: List ( ast:: ExprList { elts : params, .. } ) => {
1893+ if let [ ast:: Expr :: EllipsisLiteral ( _) ] = & params[ ..] {
1894+ // Return `None` here so that we emit a specific diagnostic at the callsite.
1895+ return None ;
1896+ }
1897+
18661898 let mut parameter_types = Vec :: with_capacity ( params. len ( ) ) ;
18671899
18681900 // Whether to infer `Todo` for the parameters
18691901 let mut return_todo = false ;
18701902
1871- // `Callable[[...], R]` — the user almost certainly meant `Callable[..., R]`
1872- if let [ sole_param] = & params[ ..]
1873- && sole_param. is_ellipsis_literal_expr ( )
1874- {
1875- if let Some ( mut diagnostic) = self . report_invalid_type_expression (
1876- sole_param,
1877- format_args ! ( "`...` is not allowed in this context in a type expression" ) ,
1878- ) {
1879- diagnostic
1880- . set_primary_message ( "Did you mean `Callable[..., <return type>]`?" ) ;
1881- }
1882- self . store_expression_type ( sole_param, Type :: unknown ( ) ) ;
1883- parameter_types. push ( Type :: unknown ( ) ) ;
1884- } else {
1885- for param in params {
1886- let param_type = self . infer_type_expression ( param) ;
1887- // This is similar to what we currently do for inferring tuple type expression.
1888- // We currently infer `Todo` for the parameters to avoid invalid diagnostics
1889- // when trying to check for assignability or any other relation. For example,
1890- // `*tuple[int, str]`, `Unpack[]`, etc. are not yet supported.
1891- return_todo |= param_type. is_todo ( )
1892- && matches ! ( param, ast:: Expr :: Starred ( _) | ast:: Expr :: Subscript ( _) ) ;
1893- parameter_types. push ( param_type) ;
1894- }
1903+ for param in params {
1904+ let param_type = self . infer_type_expression ( param) ;
1905+ // This is similar to what we currently do for inferring tuple type expression.
1906+ // We currently infer `Todo` for the parameters to avoid invalid diagnostics
1907+ // when trying to check for assignability or any other relation. For example,
1908+ // `*tuple[int, str]`, `Unpack[]`, etc. are not yet supported.
1909+ return_todo |= param_type. is_todo ( )
1910+ && matches ! ( param, ast:: Expr :: Starred ( _) | ast:: Expr :: Subscript ( _) ) ;
1911+ parameter_types. push ( param_type) ;
18951912 }
18961913
18971914 return Some ( if return_todo {
0 commit comments