@@ -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)
@@ -514,7 +514,11 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
514514 ast:: Expr :: IpyEscapeCommand ( _) => todo ! ( "Implement Ipy escape command support" ) ,
515515
516516 ast:: Expr :: EllipsisLiteral ( _) => {
517- todo_type ! ( "ellipsis literal in type expression" )
517+ self . report_invalid_type_expression (
518+ expression,
519+ "`...` is not allowed in this context in a type expression" ,
520+ ) ;
521+ Type :: unknown ( )
518522 }
519523
520524 ast:: Expr :: Starred ( starred) => self . infer_starred_type_expression ( starred) ,
@@ -639,15 +643,18 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
639643 let mut first_unpacked_variadic_tuple = None ;
640644
641645 for element in elements {
642- if element. is_ellipsis_literal_expr ( )
643- && let Some ( builder) = self . context . report_lint ( & INVALID_TYPE_FORM , tuple)
644- {
645- let mut diagnostic =
646- builder. into_diagnostic ( "Invalid `tuple` specialization" ) ;
647- diagnostic. set_primary_message (
648- "`...` can only be used as the second element \
649- in a two-element `tuple` specialization",
650- ) ;
646+ if element. is_ellipsis_literal_expr ( ) {
647+ if let Some ( builder) = self . context . report_lint ( & INVALID_TYPE_FORM , tuple) {
648+ let mut diagnostic =
649+ builder. into_diagnostic ( "Invalid `tuple` specialization" ) ;
650+ diagnostic. set_primary_message (
651+ "`...` can only be used as the second element \
652+ in a two-element `tuple` specialization",
653+ ) ;
654+ }
655+ self . store_expression_type ( element, Type :: unknown ( ) ) ;
656+ element_types. push ( Type :: unknown ( ) ) ;
657+ continue ;
651658 }
652659 let element_ty = self . infer_type_expression ( element) ;
653660 return_todo |=
@@ -720,14 +727,17 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
720727 ty
721728 }
722729 single_element => {
723- if single_element. is_ellipsis_literal_expr ( )
724- && let Some ( builder) = self . context . report_lint ( & INVALID_TYPE_FORM , tuple)
725- {
726- let mut diagnostic = builder. into_diagnostic ( "Invalid `tuple` specialization" ) ;
727- diagnostic. set_primary_message (
728- "`...` can only be used as the second element \
729- in a two-element `tuple` specialization",
730- ) ;
730+ if single_element. is_ellipsis_literal_expr ( ) {
731+ if let Some ( builder) = self . context . report_lint ( & INVALID_TYPE_FORM , tuple) {
732+ let mut diagnostic =
733+ builder. into_diagnostic ( "Invalid `tuple` specialization" ) ;
734+ diagnostic. set_primary_message (
735+ "`...` can only be used as the second element \
736+ in a two-element `tuple` specialization",
737+ ) ;
738+ }
739+ self . store_expression_type ( single_element, Type :: unknown ( ) ) ;
740+ return TupleType :: heterogeneous ( self . db ( ) , std:: iter:: once ( Type :: unknown ( ) ) ) ;
731741 }
732742 let single_element_ty = self . infer_type_expression ( single_element) ;
733743 if element_could_alter_type_of_whole_tuple ( single_element, single_element_ty, self )
@@ -1282,26 +1292,53 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
12821292
12831293 let return_type = arguments. next ( ) . map ( |arg| self . infer_type_expression ( arg) ) ;
12841294
1285- let correct_argument_number = if let Some ( third_argument) = arguments. next ( ) {
1286- self . infer_type_expression ( third_argument) ;
1287- for argument in arguments {
1288- 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+ }
12891312 }
1290- false
1313+ Type :: single_callable (
1314+ db,
1315+ Signature :: new (
1316+ Parameters :: unknown ( ) ,
1317+ return_type. unwrap_or_else ( Type :: unknown) ,
1318+ ) ,
1319+ )
12911320 } else {
1292- return_type. is_some ( )
1293- } ;
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+ } ;
12941330
1295- if !correct_argument_number {
1296- report_invalid_arguments_to_callable ( & self . context , subscript) ;
1297- }
1331+ if !correct_argument_number {
1332+ report_invalid_arguments_to_callable ( & self . context , subscript) ;
1333+ }
12981334
1299- let callable_type = if let ( Some ( parameters) , Some ( return_type) , true ) =
1300- ( parameters, return_type, correct_argument_number)
1301- {
1302- Type :: single_callable ( db, Signature :: new ( parameters, return_type) )
1303- } else {
1304- 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+ }
13051342 } ;
13061343
13071344 // `Signature` / `Parameters` are not a `Type` variant, so we're storing
@@ -1610,7 +1647,13 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
16101647 std:: slice:: from_ref ( arguments_slice)
16111648 } ;
16121649 for argument in arguments {
1613- self . infer_type_expression ( argument) ;
1650+ if argument. is_ellipsis_literal_expr ( ) {
1651+ // The trailing `...` in `Concatenate[int, str, ...]` is valid;
1652+ // store without going through type-expression inference.
1653+ self . store_expression_type ( argument, Type :: unknown ( ) ) ;
1654+ } else {
1655+ self . infer_type_expression ( argument) ;
1656+ }
16141657 }
16151658 let num_arguments = arguments. len ( ) ;
16161659 let inferred_type = if num_arguments < 2 {
@@ -1847,6 +1890,11 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
18471890 return Some ( Parameters :: gradual_form ( ) ) ;
18481891 }
18491892 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+
18501898 let mut parameter_types = Vec :: with_capacity ( params. len ( ) ) ;
18511899
18521900 // Whether to infer `Todo` for the parameters
0 commit comments